2014-02-20 27 views
4

默认情况下,Moq不会进行递归模拟。也就是说,对于没有模拟预期的成员,Moq返回默认值。例如,给定:为什么AutoFixture.AutoMoq默认进行递归模拟?

public interface IFoo 
{ 
    Bar Bar(); 
} 

public class Bar 
{ 
} 

则:

[TestMethod] 
public void RecursiveMocksAreDisabledByDefaultInMoq() 
{ 
    var foo = new Mock<IFoo>().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()); 
} 

这是为什么?并且,如何关闭AutoFixture.AutoMoq中的自动递归模拟?

感谢

 
Moq.3.1.416.3 
AutoFixture.AutoMoq.3.16.5 
+1

您可能会发现[此讨论属于AutoFoq中的默认返回值](https://foq.codeplex.com/discussions/470568)的元素有用 - AutoFoq不会OOTB更改Foq行为(导致null从方法OOTB返回值)。我也强烈推荐AutoFoq和Foq--但是我很欣赏改变嘲笑库,不是你刚做的事情。我个人最长时间不明白,一个嘲笑的图书馆如何能够比Moq更加有用,并且尽管知道它,却打了很长时间的折扣。 (注意,我用F#编写了大部分测试) –

+3

因为“AutoFixture是一个有意见的库,它所持有的观点之一是空值是无效的返回值。” http://stackoverflow.com/a/18170070/126014 –

+1

参见https://autofixture.codeplex.com/workitem/4261 –

回答

1

的问题的意见应该回答的为什么原来的问题,但随后有后续评论:

这将是很好,不过,有一个简单的方法来禁用[递归模拟]。

这不是很难做到。如果您查看AutoMoqCustomization的实现,则会启用递归模拟的use of MockPostProcessor。如果你不希望出现这种情况,你可以创建自己的自定义不这样做:

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还设置CallBasetrue,所以省略MockPostprocessor也禁用CallBase设置。