You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单元测试中模拟ComputePrice函数内Config实例的变量值?

解决ComputePrice单元测试中Config实例属性模拟问题

方案1:直接设置Config实例属性(最简单快速的方法)

因为Config.Instance返回的是可修改属性的实例,你可以在测试的Arrange阶段直接给example1和example2赋值,覆盖默认的0值。修改后的测试代码如下:

public class Tests
{
    [Test]
    public void TestComputePrice()
    {
        // Arrange
        double a = 1;
        // 直接设置Config实例的配置值
        Config.Instance.example1 = 1;
        Config.Instance.example2 = 2;
        // 预期结果:1*2 +1 =3
        double expectedResult = 3;

        // Act
        double testedResult = Data.ComputePrice(a);
        
        // Assert
        Assert.AreEqual(expectedResult, testedResult);
    }
}

如果测试用例之间需要隔离配置值,记得在每个测试前后重置Config属性,避免用例互相影响:

[SetUp]
public void Setup()
{
    // 重置为默认值
    Config.Instance.example1 = 0;
    Config.Instance.example2 = 0;
}

方案2:重构代码解耦(更符合测试友好的设计)

当前ComputePrice是静态方法且直接依赖单例Config,耦合度高,不利于长期维护和测试。推荐重构代码解耦配置依赖:

方式A:将Config作为参数传入

修改ComputePrice方法,让它接受Config实例作为参数:

public static double ComputePrice(double a, Config config) 
{
    double c = config.example1;
    double d = config.example2;
    return c * d + a;
}

测试时直接传入自定义的Config实例:

[Test]
public void TestComputePrice()
{
    // Arrange
    double a = 1;
    var testConfig = new Config { example1 = 1, example2 = 2 };
    double expectedResult = 3;

    // Act
    double testedResult = Data.ComputePrice(a, testConfig);
    
    // Assert
    Assert.AreEqual(expectedResult, testedResult);
}

方式B:依赖注入(适合非静态场景)

如果Data类可以改为非静态,通过构造函数注入Config:

public class Data
{
    private readonly Config _config;

    public Data(Config config)
    {
        _config = config;
    }

    public double ComputePrice(double a) 
    {
        double c = _config.example1;
        double d = _config.example2;
        return c * d + a;
    }
}

测试时注入自定义的Config实例:

[Test]
public void TestComputePrice()
{
    // Arrange
    double a = 1;
    var testConfig = new Config { example1 = 1, example2 = 2 };
    var data = new Data(testConfig);
    double expectedResult = 3;

    // Act
    double testedResult = data.ComputePrice(a);
    
    // Assert
    Assert.AreEqual(expectedResult, testedResult);
}

方案3:反射重置Config单例(不推荐,仅当无法修改现有代码时使用)

如果不能修改Data和Config的代码,可以用反射重置Config的_Instance字段,替换为自定义实例:

[Test]
public void TestComputePrice()
{
    // Arrange
    double a = 1;
    // 创建自定义Config实例
    var testConfig = new Config { example1 = 1, example2 = 2 };
    // 用反射获取并重置_Instance字段
    var instanceField = typeof(Config).GetField("_Instance", BindingFlags.NonPublic | BindingFlags.Static);
    instanceField.SetValue(null, new Lazy<Config>(() => testConfig));
    double expectedResult = 3;

    // Act
    double testedResult = Data.ComputePrice(a);
    
    // Assert
    Assert.AreEqual(expectedResult, testedResult);
}

这种方法属于hack手段,会破坏封装性,仅作为临时解决方案,优先推荐方案1或方案2。

内容的提问来源于stack exchange,提问作者w97802

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:10:42