Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么AutoFixture.AutoMoq默认进行递归模拟?_C#_Mocking_Moq_Autofixture - Fatal编程技术网

C# 为什么AutoFixture.AutoMoq默认进行递归模拟?

C# 为什么AutoFixture.AutoMoq默认进行递归模拟?,c#,mocking,moq,autofixture,C#,Mocking,Moq,Autofixture,默认情况下,Moq不进行递归模拟。也就是说,对于对模拟没有期望的成员,Moq返回默认值。例如,假设: public interface IFoo { Bar Bar(); } 及 然后: [TestMethod] public void recursivemocksaredisabled by defaultinmoq() { var foo=new Mock().Object; Assert.IsNull(foo.Bar()); } 但是,在AutoFixture.AutoMoq中

默认情况下,Moq不进行递归模拟。也就是说,对于对模拟没有期望的成员,Moq返回默认值。例如,假设:

public interface IFoo
{
    Bar Bar();
}

然后:

[TestMethod]
public void recursivemocksaredisabled by defaultinmoq()
{
var foo=new Mock().Object;
Assert.IsNull(foo.Bar());
}
但是,在AutoFixture.AutoMoq中,递归模拟在默认情况下处于启用状态,如中所示:

[TestMethod]
public void RecursiveMocksAreEnabledByDefaultInAutoFixture()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var foo = fixture.Create<IFoo>();
    Assert.IsNotNull(foo.Bar());
}
[TestMethod]
public void recursivemocksareenabledbydefaultinantofixture()
{
var fixture=new fixture().Customize(new AutoMoqCustomization());
var foo=fixture.Create();
Assert.IsNotNull(foo.Bar());
}
为什么呢?还有,如何在AutoFixture.AutoMoq中关闭自动递归模拟

谢谢

Moq.3.1.416.3 AutoFixture.AutoMoq.3.16.5 最小起订量3.1.416.3 AutoFixture.AutoMoq.3.16.5
对这个问题的评论应该回答最初的问题,即为什么,但还有后续的评论:

不过,如果有一种简单的方法来禁用[递归模拟],那就太好了

这并不难做到。如果您看一下
自动moqcustomization
的实现,就是它打开了递归模拟。如果您不想这样做,您可以创建自己的自定义项,但不这样做:

public class AutoNonRecursiveMoqCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        if (fixture == null)
            throw new ArgumentNullException("fixture");

        fixture.Customizations.Add(
            new MethodInvoker(
                new MockConstructorQuery()));
        fixture.ResidueCollectors.Add(new MockRelay());
    }
}

MockPostprocessor
还将
CallBase
设置为
true
,因此通过省略
MockPostprocessor
也可以禁用该
CallBase
设置。

您可能会发现有用的元素-AutoFoq不会改变Foq行为(导致
null
方法OOTB返回值)。我也强烈推荐AutoFoq和Foq,不过我很欣赏改变模拟库并不是你“只是做”的事情。我个人很长一段时间都不明白,一个模拟库怎么会比Moq更有用,尽管我知道,但我还是很长一段时间没有考虑它。(注意,我用F#编写了我的大多数测试),因为“AutoFixture是一个固执己见的库,它持有的观点之一是空值是无效的返回值。”另请参见@MarkSeemann,我知道引用的帖子。AutoFoq默认为返回空值。AutoMoq返回递归模拟。有一个不一致的地方。这是我的主要观点。正如你所知,我对固执己见的设计(特别是当你解释你通常做得非常出色的事情时)没有任何问题,我每天都非常喜欢、欣赏和使用汽车。。。直到AutoFoq将使用的地方,它目前使用Foq的1.x行为(对于尚未明确设置的属性和方法返回
null
)。 Moq.3.1.416.3 AutoFixture.AutoMoq.3.16.5
public class AutoNonRecursiveMoqCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        if (fixture == null)
            throw new ArgumentNullException("fixture");

        fixture.Customizations.Add(
            new MethodInvoker(
                new MockConstructorQuery()));
        fixture.ResidueCollectors.Add(new MockRelay());
    }
}