c# – 使用Moq进行单元测试

假设我有一个包含多个函数的普通类:

public class MyClass
{
    public int GetTotal(int myValue, string myString)
    {
        if (myValue > 10)
            return GetTotal(myValue);
        else
            return GetTotal(myString);
    }

    public int GetTotal(int myValue)
    {
        return myValue * 25 / 12 + 156;
    }

    public int GetTotal(string myString)
    {
        return myString.Length * 25 / 48 + 27;
    }
}

我想单元测试我的第一个函数并“模拟”其他函数,int GetTotal(int myValue)和int GetTotal(string myString),以便只测试main函数内的代码.我使用Moq作为模拟框架.是否有一些技巧可以让我从我想测试的函数中获取代码并模拟对其他函数的内部调用?或者我是否应该调用这样的第二个对象来模拟一切?

public class MyCalculator
{
    public int GetTotal(int myValue)
    {
        return myValue * 25 / 12 + 156;
    }

    public int GetTotal(string myString)
    {
        return myString.Length * 25 / 48 + 27;
    }
}

public class MyClass
{
    MyCalculator _Calculator;

    public MyClass(MyCalculator calculator) { _Calculator = calculator; }
    public int GetTotal(int myValue, string myString)
    {
        if (myValue > 10)
            return _Calculator.GetTotal(myValue);
        else
            return _Calculator.GetTotal(myString);
    }
}

我知道最新的是最干净的方式,但我有很多函数一个接一个地调用自己,这样就可以编写很多类.

更新

模拟实施托马斯的回答:

public class MyClass
{
    public int GetTotal(int myValue, string myString)
    {
        if (myValue > 10)
            return GetTotal(myValue);
        else
            return GetTotal(myString);
    }

    public virtual int  GetTotal(int myValue)
    {
        return myValue * 25 / 12 + 156;
    }

    public virtual int GetTotal(string myString)
    {
        return myString.Length * 25 / 48 + 27;
    }
}

[TestClass]
public class Test
{
    [TestMethod]
    public void MyClass_GetTotal()
    {
        Mock<MyClass> myMockedClass = new Mock<MyClass>() {CallBase = true};

        myMockedClass.Setup(x => x.GetTotal(It.IsAny<int>())).Returns(1);
        myMockedClass.Setup(x => x.GetTotal(It.IsAny<string>())).Returns(2);

        var actual = myMockedClass.Object.GetTotal(0,string.Empty);

        Assert.AreEqual(2,actual);
    }
}

更新2

请参阅Gishu的答案,以便更全面地了解这个“问题”.

最佳答案
当然!在Rhino Mocks中,您可以使用部分模拟来实现该目的.像这样创建一个新的模拟:

var mock = MockRepository.GeneratePartialMock<MyClass>();

然后你可以模拟或存根那些你不想要这样调用的方法:

mock.Stub(x => x.GetTotal(10)).Return(42);

它需要您的GetTotal方法是虚拟的.

转载注明原文:c# – 使用Moq进行单元测试 - 代码日志