2013-11-13 7 views
4

Я использую NUnit, Moq и StructureMap.Проверка Moq завершается неудачей, когда SelectMany

У меня есть следующий 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 не вызывается в mocks. Однако, если я поменяю реализацию класса SUT к этому:

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

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


     return ... 
    } 
} 

тест пройден! Разница заключается в том, что вместо итерации с помощью SelectMany i я использую foreach, но результаты теста различаются (во втором случае CustomMethods вызываются в mocks).

Может ли кто-нибудь объяснить это поведение?

ответ

7

Я думаю, что это может быть случай отсроченного исполнения. SelectMany не выполняется немедленно. Возвращаемый IEnumerable должен быть указан для ваших методов, которые будут вызваны. Попробуйте добавить ToList() после метода SelectMany(), чтобы заставить IEnumerable, возвращенный с SelectMany для оценки.

+1

Пятно на! Так было. Поэтому, чтобы уточнить: мои методы будут вызваны, как только я буду использовать возвращаемое значение метода SUT - это когда IEnumerable будет оценен. –

+0

@JarekMazur Да, вы правы. И поэтому вызов toList() 'может перейти в ваш модульный тест. –

Смежные вопросы