我想测试我的Func
类型是否已实际执行。为此,我创建了一个Mock
,但我遇到了来自Autofixture的Exception
。我尝试Freeze
只Func
(没有Mock
),这有效。有人可以解释发生了什么或指导我采取正确的方式吗?
异常消息:
类型' Ploeh.AutoFixture.Kernel.IllegalRequestException'的例外情况发生在Ploeh.AutoFixture.dll但未在用户代码中处理 附加信息:检测到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
答案 0 :(得分:4)
此行为归因于AutoConfiguredMoqCustomization
。
使用AutoConfiguredMoqCustomization
自定义AutoFixture时,它会将Mock实例的创建中继到特殊构建器。
但是,此构建器获取内部类型Func<int,DomainClassDummy>
并创建一个模拟,传递其构造函数的两个参数:object
和IntPtr
,这就是问题所在。< / p>
委托的默认构建器,使用Linq Lambda Expression创建其实例。
要使其正常工作,您必须自己创建模拟并将其注入AutoFixture。注入它与冻结相同,除非您自己指定实例,而不是告诉AutoFixture为您创建一个。
这是你应该做的:
var mockOfFunc = new Mock<Func<int, DomainClassDummy>>();
F.Inject(mockOfFunc);
答案 1 :(得分:2)
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
}