模拟内部函数的响应但测试外部函数

时间:2016-02-06 01:26:20

标签: c# unit-testing mocking

我有这样的C#代码设置。

public class Client : IClient
{
    public string funcA()
    {
       var output = funcB(1);
       //Do something on output and produce finalResult
       return finalResult;
    }

    public string funcB(int x)
    {
         // Some operations on produces string result
         return result;
    }
}

我想模拟funcB输出,但让funcA根据funcB的输出执行。

在我的测试课程中,我会执行以下操作:

public class MockClient
{
    private Mock<IClient> _mockClient;

    public MockClient()
    {
        _mockClient = new Mock<IClient>();
    }

    [TestMethod]
    public void TestClient()
    {
        _mockClient.Setup(foo => foo.funcB(It.IsAny<int>())).Returns("test");
        var testOutput = _mockClient.Object.funcA();
    }
}

变量testOutput返回NULL。我理解为什么,因为该对象是从一个接口创建的。我不确定如何解决这个问题。对此的任何输入都会有所帮助。

2 个答案:

答案 0 :(得分:1)

我假设您使用基于语法的Moq?如果是这样,您可以使用“Partial Mocks”。例如:

将funcB更改为虚拟

public virtual string funcB(int x)
{
    // Some operations on produces string result
    return result;
}

然后模拟具体类型并将CallBase属性设置为true:

[TestMethod]
public void TestClient()
{
    Mock<Client> _mockClient = Mock<Client>();
    _mockClient.CallBase = true;
    _mockClient.Setup(foo => foo.funcB(It.IsAny<int>())).Returns("test");
    var testOutput = _mockClient.Object.funcA();
}

答案 1 :(得分:1)

以上示例在Moq语法中完全正确。但是将功能虚拟化还是不虚拟化 - 它是基于您,客户等目的和需求的生产决策。将funcB更改为虚拟仅用于测试 - 听起来不合理。

您可以使用Typemock Isolator来测试原始代码,请参阅:

     public class Client : IClient
     {
        public string funcA()
        {
            var output = funcB(1);
            //Do something on output and produce finalResult
            var finalResult = "B result: " + output;
            return finalResult;
        }

        public string funcB(int x)
        {
            // Some operations on produces string result
            return "result";
        }
    }

    [TestMethod, Isolated]
    public void TestMethod()
    {
        //Arrange
        var foo = new Client();
        Isolate.WhenCalled(() => foo.funcB(0)).WillReturn("test");

       //Act
       var output = foo.funcA();

       //Assert
       Assert.AreEqual("B result: test", output);
   }