C# 为什么AutoFixture.AutoMoq默认进行递归模拟?
默认情况下,Moq不进行递归模拟。也就是说,对于对模拟没有期望的成员,Moq返回默认值。例如,假设: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中
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());
}
}