模拟方法不传递正确的值

Mocked method do not pass correct value

我想了解模拟在 Xunit 中如何使用 AutoFixture 工作。我已经创建了服务和存储库 类 及其接口。模拟方法应该传递与默认值不同的值。

模拟方法总是传递默认值而不是我在“.Returns()”中写入的值。我已经尝试过 AutoConfiguredMoqCustomization,但它提供了完全随机的值,我无法取回。

Repository.cs

public class Repository : IRepository
{
    public int GetInt()
    {
         return 999;
    }
}

Service.cs

public class Service : IService
{        
    private readonly Repository _repository;

    public Service()
    {
        _repository = new Repository();
    }

    public string GetStringFromInt()
    {
        return _repository.GetInt().ToString();
    }
}

测试

    [Fact]
    public void Test()
    {
        var fixture = new Fixture().Customize(new AutoMoqCustomization());
        var repositoryMock = fixture.Create<Mock<IRepository>>();
        var service = fixture.Create<Service>();

        repositoryMock.Setup(x => x.GetInt()).Returns(1);
        var act = service.GetStringFromInt();

        Assert.Equal("1", act);
    }

如您所见,Repository 中的默认值是 999,我期望从 repositoryMock 得到 1,但结果是“999”而不是“1”。

哦,我明白我的问题了。当我使用自动最小起订量测试服务声明参数时,必须在所有模拟存储库之后

测试

[Theory, AutoMoqData]
public void Test([Frozen] Mock<IRepository> repositoryMock, Service service)
{
    ...
}

属性

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute() : base(GetDefaultFixture)
    {
    }

    private static IFixture GetDefaultFixture()
    {
        return new Fixture().Customize(new AutoMoqCustomization());
    }
}

你做错了 DI,你没有将存储库注入你的服务。 像这样尝试。

    public class Repository : IRepository
    {
        public int GetInt()
        {
            return 999;
        }
    }

    public class Service : IService
    {
        IRepository Repository;
        public Service(IRepository repository)
        {
            this.Repository = repository;
        }
        public string GetStringFromInt()
        {
            return Repository.GetInt().ToString();
        }
    }

现在当你模拟 IRepository 时,你可以将它添加到服务中。

您正在构造函数中使用新的 Repository(),因此您正在使用该实现

你应该先冻结你的模拟。当您在 AutoFixture 上调用 Create 时,它​​每次都会为您创建一个新实例。在修改后的代码中尝试以下操作(您在构造函数中使用该类型的接口)。

public class ServiceTests
{
  private readonly IFixture fixture = new Fixture().Customize(new AutoMoqCustomization());

  public ServiceTests() 
  {
    fixture.Register<IService>(() => fixture.Create<Service>());
  }

  [Fact]
  public void Test()
  {
    // Arrange
    var repositoryMock = fixture.Freeze<Mock<IRepository>>();
    repositoryMock.Setup(x => x.GetInt()).Returns(1);

    var service = fixture.Create<IService>();

    // Act
    var act = service.GetStringFromInt();

    // Verify
    Assert.Equal("1", act);
  }
}

为了检查您是否正确设置了autofixture,您可以在以后的单元测试中尝试以下操作。


var repo1 = fixture.Create<IRepository>();
var repo2 = fixture.Create<IRepository>();

Assert.Equal(repo1.GetHashCode(), repo2.GetHashCode());

如果以上都失败了,说明你还没有冻结一个类型。这些代码行让我在过去省去了很多头疼的事情...