最小起订量设置单元测试

Moq setup unit test

我有一个简单的方法:

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 与整个方法几乎相同的语句?

只有当 IMyService 被用作您要测试的另一个 class 的依赖项时,您才会这样做。如果 IMyService 是被测系统,那么您就不会这样做,因为您没有模拟要测试的系统。您使用目标的实际实例 class.

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

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 将对尝试测试 class.

有意义
[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);
}