Unit testing 是否可以冻结func的模拟?

Unit testing 是否可以冻结func的模拟?,unit-testing,autofixture,automoq,Unit Testing,Autofixture,Automoq,我想测试我的Func类型是否实际执行。为此,我创建了一个Mock,但在Autofixture中遇到了一个异常。我试着只冻结Func(不包括Mock),这样就行了。有人能解释一下发生了什么,或者指导我正确的方法吗 异常消息: Ploeh.AutoFixture.dll中发生类型为“Ploeh.AutoFixture.Kernel.IllegalRequestException”的异常,但未在用户代码中处理 其他信息:检测到IntPtr请求。这是一个不安全的资源,如果使用它,将使进程崩溃,因此请求被

我想测试我的
Func
类型是否实际执行。为此,我创建了一个
Mock
,但在Autofixture中遇到了一个
异常。我试着只冻结
Func
(不包括
Mock
),这样就行了。有人能解释一下发生了什么,或者指导我正确的方法吗

异常消息:

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

代码:

公共类DomainClassDummy
{
公共int Id{get;set;}
}
var frozenFunc=F.Freeze()//作品
var frozenMockOfFunc=F.Freeze()//失败

此行为是由于
自动配置MoqCustomization
造成的

当AutoFixture使用
AutoConfiguredMoqCustomization
进行自定义时,它会将模拟实例的创建传递给一个特殊的生成器。 但是,此生成器获取内部类型
Func
,并创建一个模拟,传递其构造函数的两个参数:
object
IntPtr
,问题就在这里

代理的默认生成器使用Linq Lambda表达式创建其实例

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

以下是您应该做的:

var mockOfFunc = new Mock<Func<int, DomainClassDummy>>();
F.Inject(mockOfFunc);
var mockOfFunc=new Mock();
F.注入(mockOfFunc);

Marcio Rinaldi给出的解释在技术上是正确的,但我发现解决方案不令人满意,因此我将此功能添加到了

此测试现在通过:

[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
}
[事实]
public void FixtureCanFreezeUsableMockOfFunc()
{
//夹具设置
var fixture=new fixture().Customize(new AutoMoqCustomization());
var expected=fixture.Create();
var mockOfFunc=fixture.Freeze();
模拟基金
.Setup(f=>f(It.IsAny(),1337m))
.回报(预期);
//运动系统
var actual=mockOfFunc.Object(Guid.NewGuid(),1337m);
//核实结果
断言。相等(预期、实际);
//拆卸
}

您使用的是什么版本的Moq和AutoFixture?您是自定义夹具还是按原样使用它?我使用的是Autofixture 3.30.8,并且我正在将其最大化:F=new Fixture().Customize(new AutoConfiguredMoqCustomization());哇!这正是我要找的。我会试试看。谢谢
[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
}