C# 如果一个函数依赖于另一个函数,那么如何使用模拟数据来安置该内部函数以进行单元测试?

C# 如果一个函数依赖于另一个函数,那么如何使用模拟数据来安置该内部函数以进行单元测试?,c#,visual-studio,unit-testing,testing,C#,Visual Studio,Unit Testing,Testing,所以我有这样的想法: class MyClass { private myVar; public MyClass(someValue) { // Performs some operation to determine myVar } public double calculateThing() { // Returns some arithmetic operation on myVar } public d

所以我有这样的想法:

class MyClass {
    private myVar;

    public MyClass(someValue) {
        // Performs some operation to determine myVar
    }

    public double calculateThing() {
        // Returns some arithmetic operation on myVar
    }

    public double calculateOtherThing() {
        newVar = calculateThing();
        // Returns some arithmetic operation on newVar
    }
}

calculateThingUnitTest() {
    MyClass class = new MyClass(someValue);

    Assert::AreEqual(someConstant, class.CalculateThing());
}

calculateOtherThingUnitTest() {
    MyClass class = new MyClass(someValue);

    Assert::AreEqual(someOtherConstant, class.CalculateOtherThing());
}
很明显,calculateThingUnitTest是一个合适的单元测试,因为它初始化一个类,在构造函数中给它一些文本定义的独立值,并且它所做的断言仅基于calculateThing,所以它测试应用程序的一个单元

但是,calculateOtherThingUnitTest调用calculateOtherThing,然后调用calculateThing来确定结果是否正确。所以,如果calculateThing最终失败,Calculate其他东西也会失败

为了防止这种情况发生,您可能希望使用一些模拟值来代替calculateThing,您可以通过在MyClass中插入一个新成员变量并将calculateThing加载到该成员变量中来实现这一点。然后在调用calculateOtherThing之前,您可以在这个成员变量中插入一个文本值,然后进行适当的单元测试

然而,添加一个新的成员变量并向公众公开它似乎是非常过分的。有没有更好的方法来实现这一点


注意:虽然我使用的是伪代码,但我使用的是Visual Studio.Net单元测试项目中的C语言。

您需要的是部分模拟。您需要模拟未测试的方法。并且,您需要保持方法在测试中,因为它是默认实现。因此,当您调用测试中的方法时,不会调用所有其他方法,因为它们是模拟的

所以你可以模拟计算,然后直接测试其他方法


其实这并不是一个问题,更重要的是,在我刚刚接触的单元测试领域,这似乎是一种不好的做法,所以我很好奇您将实施什么策略使其成为好的做法。同样在我的具体案例中,将方法保持为非静态将有利于总体设计。假设方法是非静态的,我想我是在问在这种情况下实现单元测试的正确方法是什么。隔离目标函数的困难应该是该函数有太多责任的一个指标,这是一个SRP-单一责任原则违反,因为它涉及到可靠的代码。单元测试糟糕的代码不会改变代码设计糟糕的事实。不过,它应该有助于识别糟糕的代码,以便对其进行相应的重构。你可能误解了我的解释。这正是我想要的!谢谢实际上,我自己刚刚想出了一个解决方案:创建一个覆盖内部函数返回值的扩展类。这正是我们所要达到的,但要以更干净的方式来实现。@ShaneDuffy欢迎您。你的方法也有效。尽管我有点怀疑,当我们有好的工具可供使用时,是否为了测试而对架构进行了太多的更改。