Moq设置单元测试

时间:2016-12-08 16:45:04

标签: c# .net unit-testing moq xunit

我有一个简单的方法,如:

public class MyService : IMyService
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

public interface IMyService
{
    int Add(int x, int y);
}

我用这个方法写了一个单元测试:

public void PassingTest()
{
    var mock = new Mock<IMyService>();

    mock.Setup(x => x.Add(It.IsAny<int>(), It.IsAny<int>())).Returns<int, int>((x, y) => { return x + y; });

    var svc = mock.Object;

    var result = svc.Add(3, 3);
    var result2 = svc.Add(2, 5);
    result.Should().Be(6);
    result2.Should().Be(7);
}

这段代码还可以吗?为什么我必须写一个与整个方法几乎相同的Returns语句?

1 个答案:

答案 0 :(得分:0)

如果要将IMyService用作您要测试的另一个类的依赖项,则只会执行此类操作。如果IMyService是受测试的系统,那么您就不会嘲笑您要测试的系统。您使用目标类的实际实例。

让我们在一个非常简单的例子中说,我们有一个这样的课程。

public class SomeClass {
    public SomeClass(IMyService service) {
        this.service = service;
    }
    private readonly IMyService service;

    public int SomeMethodThatUsesMyService(int input) {
        int someConstant = 10;

        var result = service.Add(someConstant, input);
        return result;
    }
}

如果IMyService的实现执行了一些依赖于IO的处理,并且很难自行测试。然后,模拟IMyService对于尝试测试该类是有意义的。

[Fact]
public void Given_Input_SomeMethodThatUsesMyService_Should_Increase_By_Ten() {
    //Arrange
    var expected = 14;

    var mock = new Mock<IMyService>();

    mock.Setup(x => x.Add(It.IsAny<int>(), It.IsAny<int>())).Returns<int, int>((x, y) => { return x + y; });

    var svc = mock.Object;

    var sut = new SomeClass(svc);

    //Act
    var result = sut.SomeMethodThatUsesMyService(4);

    //Assert
    result.Should().Be(expected);
}