首页 > 解决方案 > Frozen Mock 返回 null 但在 Test 方法中工作正常

问题描述

我正在尝试测试一项服务,该服务利用提供者从数据库中获取一些值并在返回一些值之前在服务中使用它。调试测试时,模拟的提供者工作正常。但是当完整运行测试时,提供者总是返回 null。

测试用例

[Theory]
[AutoStackoverFlowData]
public async Task TestingService(Service sut, [Frozen] Mock<IProvider> providerMock)
{
    providerMock.Setup(x => x.GetGreeting(It.IsAny<int>())).ReturnsAsync("Hello Developer");
    var s = providerMock.Object.GetGreeting(123); //works returns "Hello Developer"
    var greeting = sut.SayHello();
    Assert.Equal(greeting, "Hello Developer");
}

public class AutoStackoverFlowData : AutoDataAttribute
{
    public AutoStackoverFlowData() : this(new AutoMoqCustomization()) { }

    public AutoStackoverFlowData(params ICustomization[] customization)
            : base(() => new Fixture().Customize(new AutoMoqCustomization())) { }
}

服务

public class Service
{
    private readonly IProvider provider
    public Service(IProvider provider)
    {
        this.provider= provider;
    }

    public async Task<string> SayHello()
    {
        int someNum= 123;
        var temp = await subProvider.GetGreeting(someNum);
        return temp;
    }
}

界面

public interface IProvider
{
    Task<string> GetGreeting(int id);
}

标签: c#unit-testingmoqautofixture

解决方案


使用[冰冻]时,顺序很重要。始终将 [Frozen] 变量作为测试用例中的第一个参数。这是一个简单的修复:

[Theory]
[AutoStackoverFlowData]
public async Task TestingService([Frozen] Mock<IProvider> providerMock, Service sut)
{
    providerMock.Setup(x => x.GetGreeting(It.IsAny<int>())).ReturnsAsync("Hello Developer");
    var s = providerMock.Object.GetGreeting(123);
    var greeting = await sut.SayHello();
    Assert.Equal("Hello Developer", greeting);
}

推荐阅读