4

我正在使用 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());
    }

自定义接口:

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 ...
    }
}

测试通过!不同之处在于,我使用 foreach 而不是使用 SelectMany 进行迭代,但测试结果不同(在第二种情况下,CustomMethods 确实在模拟上被调用)。

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

4

1 回答 1

8

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

于 2013-11-13T13:14:05.300 回答