0

我试图了解在 Xunit 中如何使用 AutoFixture 进行模拟。我创建了 Service 和 Repository 类及其接口。模拟方法应该传递与默认值不同的值。

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

存储库.cs

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

服务.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());
    }
}
4

2 回答 2

0

您做错了 DI,您没有将 Repository 注入您的服务中。像这样试试。

    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 时,您可以将其添加到 Service。

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

于 2019-07-25T15:16:52.153 回答
0

你应该先冻结你的模拟。当您在 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());

如果上述失败,则表明您尚未冻结类型。过去,这些代码行让我省了很多麻烦……

于 2019-08-21T11:07:06.907 回答