2

我想测试我的Func类型是否真的被执行了。为此,我创建了一个Mock,但我遇到了Exception来自 Autofixture 的一个。我试图Freeze只是Func(没有Mock)并且这有效。有人可以解释发生了什么或指导我采取正确的方法吗?

异常消息:

Ploeh.AutoFixture.dll 中出现“Ploeh.AutoFixture.Kernel.IllegalRequestException”类型的异常,但未在用户代码中处理附加信息:检测到对 IntPtr 的请求。这是一个不安全的资源,如果使用它将使进程崩溃,因此请求被拒绝。IntPtr 请求的常见来源是对诸如 Func 或 Action 之类的委托的请求。如果是这种情况,预期的解决方法是通过指定适当的创建策略来自定义(注册或注入)违规类型。

代码:

public class DomainClassDummy
{
    public int Id { get; set; }
}

var frozenFunc = F.Freeze<Func<int, DomainClassDummy>>(); //works
var frozenMockOfFunc = F.Freeze<Mock<Func<int,DomainClassDummy>>>(); //fails 
4

2 回答 2

4

这种行为是由于AutoConfiguredMoqCustomization.

当使用 自定义 AutoFixture 时AutoConfiguredMoqCustomization,它​​将 Mock 实例的创建传递给一个特殊的构建器。但是,此构建器获取内部类型并从中Func<int,DomainClassDummy>创建一个模拟,传递其构造函数的两个参数:这就是问题所在。objectIntPtr

委托的默认构建器使用 Linq Lambda 表达式创建其实例。

要使其工作,您必须自己创建模拟并将其注入 AutoFixture。注入它与冻结相同,只是您自己指定实例,而不是告诉 AutoFixture 为您创建一个。

这是你应该做的:

var mockOfFunc = new Mock<Func<int, DomainClassDummy>>();
F.Inject(mockOfFunc);
于 2015-07-30T17:27:53.243 回答
3

Marcio Rinaldi 给出的解释在技术上是正确的,但我发现解决方案并不令人满意,所以我在AutoFixture.AutoMoq 3.31.1中添加了这个功能。

该测试现在通过:

[Fact]
public void FixtureCanFreezeUsableMockOfFunc()
{
    // Fixture setup
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var expected = fixture.Create<Uri>();
    var mockOfFunc = fixture.Freeze<Mock<Func<Guid, decimal, Uri>>>();
    mockOfFunc
        .Setup(f => f(It.IsAny<Guid>(), 1337m))
        .Returns(expected);

    // Exercise system
    var actual = mockOfFunc.Object(Guid.NewGuid(), 1337m);

    // Verify outcome
    Assert.Equal(expected, actual);
    // Teardown
}
于 2015-08-02T16:06:03.653 回答