如何模拟另一个方法内部调用的方法?

时间:2014-06-24 10:10:43

标签: c# unit-testing moq

我想用一个例子来解释我的问题。

Class A
{
    Fun1()
    {
        // some code
        B obj2 = new B();
        obj2.Fun2();
    }
}

Class B
{
    Fun2() 
    {
        // some code
    }
}

// Test Class for Class A
Class A_Test
{
    Fun1_Test()
    {
        A obj1 = new A();
        A.Fun1();
    }
}

我在这里呼叫Fun1,呼叫fun2()。我想模拟对fun2()的调用。

我只需要在Fun1()中初始化B类对象,我不想使用构造函数来做它。

可以模拟对fun2()的调用吗?

2 个答案:

答案 0 :(得分:6)

你不能,因为Fun2是在 Fun1内创建的对象的实例方法。

由于A取决于B,如果您希望实现真正的隔离,B应注入A

您还应该“依赖于抽象”,如依赖性倒置原则所宣传的那样。让B实现一个界面IB,并使A取决于IB。然后,您模拟接口IB并注入该模拟。

class A
{
    public Fun1(IB ib) { ib.Fun2(); }
}

interface IB
{
    Fun2();
}

class B : IB
{
    public Fun2() {}
}

// Test Class for Class A
Class A_Test
{
    Fun1_Test()
    {
        var bMock = new Mock<IB>();
        bMock.Setup(b => b.Fun2());

        A obj1 = new A();
        A.Fun1(bMock.Object);
    }
}

读:

  1. Dependency Inversion Principle
  2. Dependency Injection

答案 1 :(得分:1)

经典示例,显示如何无法对特定组件进行单元测试,对组件进行REFACTOR!

这就是任何模拟框架强制你做的爱 - 编写解耦代码。

在您的示例中,A类与B的具体实现非常紧密地结合在一起。您可以使用(如大多数答案所示)依赖注入来解耦它。通过这样做,你最终将取决于IB抽象,而不是任何具体的实现。