我正在使用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会在模拟上调用)。
有人可以解释这种行为吗?
答案 0 :(得分:8)
我认为这可能是延迟执行的情况。 SelectMany
不会立即执行。必须枚举返回的IEnumerable
以便调用方法。尝试在ToList()
方法之后添加SelectMany()
,以强制评估从IEnumerable
返回的SelectMany
。