SelectMany时Moq验证失败

时间:2013-11-13 13:07:12

标签: c# linq unit-testing moq structuremap

我正在使用NUnit,Moq和StructureMap。

我有以下NUnit测试:

    [Test]
    public void ShouldCallCustomMethod_ForAllICustomInterfaceMocks()
    {
        var customInterfaceMock1 = new Mock<ICustomInterface>();
        var customInterfaceMock2 = new Mock<ICustomInterface>();

        ObjectFactory.Inject(customInterfaceMock1.Object);
        ObjectFactory.Inject(customInterfaceMock2.Object);

        var sut = new SUT();
        sut.MethodThatShouldCallCustomMethodOnMocks();

        customInterfaceMock1.Verify(m => m.CustomMethod());
        customInterfaceMock2.Verify(m => m.CustomMethod());
    }

ICustomInterface:

public interface ICustomInterface
{
    IEnumerable<Type> CustomMethod();
}

现在,如果SUT类的实现如下:

public class SUT
{
    public IEnumerable<Type> MethodThatShouldCallCustomMethodOnMocks()
    {
        var result = ObjectFactory.GetAllInstances<ICustomInterface>()
             .SelectMany(i => i.CustomMethod());


        return result;
    }
}
由于没有在模拟上调用CustomMethod方法,

从上面进行测试失败。 但是,如果我将SUT类的实现更改为:

public class SUT
{
    public IEnumerable<Type> MethodThatShouldCallCustomMethodOnMocks()
    {
        var customInterfaceInstances = ObjectFactory.GetAllInstances<ICustomInterface>();

        foreach (var instance in customInterfaceInstances)
              instance.CustomMethod();


        return ...
    }
}
测试通过! 区别在于,不是使用SelectMany进行迭代,而是使用foreach,但测试结果不同(在第二种情况下,CustomMethods会在模拟上调用)。

有人可以解释这种行为吗?

1 个答案:

答案 0 :(得分:8)

我认为这可能是延迟执行的情况。 SelectMany不会立即执行。必须枚举返回的IEnumerable以便调用方法。尝试在ToList()方法之后添加SelectMany(),以强制评估从IEnumerable返回的SelectMany