Autofixture MOQ-冻结模拟的类防止设置



我想了解为什么我的测试在冻结模拟的类而不是模拟界面

时失败
[Fact]
public void MethodeName()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var webRequestMock = fixture.Freeze<Mock<MyWebRequest>>(); // freezing a class + setuping a return value
    webRequestMock.Setup(a => a.GetData())
    .Returns("Foo");
    var myService = fixture.Create<MyService>();
    var actual = myService.GetData();
    webRequestMock.Verify(a => a.GetData(), Times.Once()); // Failed it's never called once
    Assert.Equal("Foo", actual); // Failed, if we comment previous line, 'actual' value is always empty
}
public class MyService
{
    private readonly MyWebRequest _request;
    public MyService(MyWebRequest request)
    {
        _request = request;
    }
    public string GetData()
    {
        var data = _request.GetData();
        return data;
    }
}
public class MyWebRequest 
{
    public virtual string GetData() // you can see here, the method is well virtual, and should be overridable by moq.
    {
        return string.Empty;
    }
}

1/如果我尝试使用模拟接口,则可以。

[Fact]
public void MethodeName()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    const string expected = "Foo";
    var webRequestMock = fixture.Freeze<Mock<IMyWebRequest>>();
    webRequestMock.Setup(a => a.GetData())
    .Returns("Foo");
    var myService = fixture.Create<MyService>();
    var actual = myService.GetData();
    webRequestMock.Verify(a => a.GetData(), Times.Once()); // Success
    Assert.Equal(expected, actual); // Success
}
public class MyService
{
    private readonly IMyWebRequest _request;
    public MyService(IMyWebRequest request)
    {
        _request = request;
    }
    public string GetData()
    {
        var data = _request.GetData();
        return data;
    }
}
public interface IMyWebRequest
{
    string GetData();
}
public class MyWebRequest : IMyWebRequest
{
    public virtual string GetData()
    {
        return string.Empty;
    }
}

2/如果我使用'注入'而不是冻结,则有效:

[Fact]
public void MethodeName()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    const string expected = "Foo";
    var webRequestMock = new Mock<MyWebRequest>(); 
    webRequestMock.Setup(a => a.GetData()).Returns("Foo");
    fixture.Inject(webRequestMock.Object);
    var myService = fixture.Create<MyService>();
    var actual = myService.GetData();
    webRequestMock.Verify(a => a.GetData(), Times.Once()); // Success
    Assert.Equal(expected, actual); // Success
}
public class MyService
{
    private readonly MyWebRequest _request;
    public MyService(MyWebRequest request)
    {
        _request = request;
    }
    public string GetData()
    {
        var data = _request.GetData();
        return data;
    }
}
public class MyWebRequest 
{
    public virtual string GetData()
    {
        // make WebRequest
        return string.Empty;
    }
}

我的自动固定版本:3.6.5.0

MyWebRequest是一个具体(非吸收)类, autofixture.automoq 不会创建使用 moq 的创建。这是 by Design ,因为 autofixture 内核已经处理了"正常"类的创建。

,如果您愿意,可以更改此行为。不过,通常,我会考虑必须这样做的气味。但是,在这种情况下很难说,因为您在将问题减少到最小的repro方面做得很好。但是,问题在于此处介绍的是,MyService不会添加任何值。我确定这不是您的真实代码的样子,但是由于我无法猜测您的真实代码是什么样子,所以我无法确定是否可以使用更好的设计。

最新更新