模拟由函数调用的函数,您将进行单元测试.使用moq

pus*_*ser 1 c# unit-testing moq

例如,您正在测试getSomeString.

public class Class1
{
    public Class1() {}

    public string getSomeString(string input)
    {
        //dosomething

        OtherClass class = new OtherClass();

        return class.getData();
    }
}

public class OtherClass
{
    public OtherClass() {/*some data*/}    

    public string getData()
    {
        //do something

        string aString = getAString(Input);

        //do something
    }

    public virtual string getAString(string input);
    {
        //do something to be mocked
        return somethingToBeMocked;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你需要单元测试来模拟出来getAString.你怎么做到这一点?

我试过只是模拟getAString并希望测试使用模拟值,但这不起作用.

我试过模拟Class1并将单元测试设置为class1模拟对象,但我无法弄清楚如何使模拟getAString传递给模拟class1.

我无法弄清楚该怎么做.

Ser*_*kiy 6

你不能只采取任何代码和单元测试它.代码应该是可测试的.什么是可测试代码?这是一个依赖于抽象而不是实现的代码.避免依赖于实现的唯一方法是通过依赖注入提供它们:

public class Class1()
{
    private IOtherClass _otherClass; // depend on this abstraction

    public Class1(IOtherClass otherClass) // constructor injection
    {
        _otherClass = otherClass;
    }

    public string getSomeString(string input)
    {
        //dosomething
        return _otherClass.getData(); // you don't know implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

IOtherClass接口由实施OtherClass

public interface IOtherClass
{
     string getData();
}
Run Code Online (Sandbox Code Playgroud)

现在你的类依赖于抽象,你可以模拟测试的抽象:

string data = "Foo";
Mock<IOtherClass> otherClassMock = new Mock<IOtherClass>();
otherClassMock.Setup(oc => oc.getData()).Returns(data);
var class1 = new Class1(otherClassMock.Object);
// Act
string result = class1.getSomeString("Bar");
// Assert
Assert.That(result, Is.EqualTo(data));
otherClassMock.VerifyAll(); // check dependency was called
Run Code Online (Sandbox Code Playgroud)

  • 好答案.从技术上讲,在Moq中可以模拟一个类(而不是接口),并且所讨论的方法是`virtual`,所以可以在不引入接口的情况下完成,但接口可能是一个很好的做法. (2认同)
  • `getData`的正常实现在`OtherClass`中.当您测试代码时,使用Moq生成`IOtherClass`的模拟实现.当你不进行单元测试时,你只需通过构造函数将一个新的`OtherClass`实例传递给`Class1`. (2认同)