2010-04-07 4 views

ответ

5

нашел ответ я после

repository.Expect(action => action.Find<Entity>(x => x.ID == 0)) 
      .IgnoreArguments() 
      .Return(entities) 
      .Repeat 
      .Any(); 
+3

Это тот же самый вывод, к которому я пришел, но, к сожалению, он все еще оставляет дыру в моей способности к единичному тесту (и, как я полагаю). Если у меня был тест, требующий нескольких вызовов в репозиторий. Метод FID с использованием разных параметров, как мне настроить макет для этого? Мне нужно высмеять выражение >, а ссылка, созданная для выражения при настройке макета, не будет эквивалентна выражению, которое создается позже в коде, потому что это будет новая ссылка на эквивалентное выражение Expression. – Mark

+0

Кто-нибудь знает хорошее решение проблемы, которую сказал Марк? – Jonna

+0

Проверьте это [ссылка] (http://blog.spinthemoose.com/2011/07/28/using-rhino-mocks-whencalled-remember-to-return/). 'mockRepo.Expect (r => r.Get (Arg >>. Is.Anything)). WhenCalled (invocation => ...' позволяет вам улавливать все вызовы, а затем возвращать значение что зависит от входного лямбда-выражения. –

5

В модульном тесте у вас есть тестируемая система (SUT) и ее сотрудники. Цель насмешки заключается в том, чтобы заменить соавторов тем, что у вас есть полный контроль над. Таким образом, вы можете настроить различные тестовые примеры, и вы можете сосредоточиться на тестировании только поведения тестируемой системы и ничего другого.

В этом случае я предполагаю, что объект rep является SUT. Лямбда, которую вы переходите на метод SUT Find, может считаться сотрудником. Поскольку у вас уже есть полный контроль над этой лямбдой, на самом деле не имеет смысла пытаться издеваться над ним с Rhino Mocks.

Я попытаюсь привести пример модульного теста с участием Rhino Mocks и lambdas в любом случае ;-) Это пример теста, который создает предикат-заглушку, который всегда возвращает false, и который проверяет, что метод Find действительно вызвал этот предикат :

[Test] 
public void Find_returns_nothing_if_predicate_always_false() 
{ 
    var predicateStub = MockRepository.GenerateStub<Func<Entity,bool>>(); 
    predicateStub.Stub(x => x(Arg<Entity>.Is.Anything)).Return(false); 

    var repository = new Repository(); 
    var entities = repository.Find(predicateStub); 

    Assert.AreEqual(0, entities.Count(), 
     "oops, got results while predicate always returns false"); 
    predicateStub.AssertWasCalled(x => x(Arg<Entity>.Is.Anything)); 
} 

Конечно, как и в вашем собственном примере, вам действительно не нужны Rhino Mocks здесь. Весь смысл синтаксиса лямбда, чтобы сделать его легко обеспечить реализацию на месте:

[Test] 
public void Find_returns_nothing_if_predicate_always_false() 
{ 
    bool predicateCalled = false; 
    Func<Entity,bool> predicate = x => { predicateCalled = true; return false; }; 

    var repository = new Repository(); 
    var entities = repository.Find(predicate); 

    Assert.AreEqual(0, entities.Count(), 
     "oops, got results while predicate always returns false"); 
    Assert.IsTrue(predicateCalled, "oops, predicate was never used"); 
} 
+0

+1 Я никогда не видел лямбда, которая нуждалась в насмешливости. – Jay

+0

Да, вы правы, но все, что я пытаюсь сделать, это Mock строка кода на данный момент, поскольку я не тестирую эту строку. – Coppermill

0

Таким образом, мы не можем выйти .. потому что из-за IgnoreArguments() он никогда не войдет внутрь и не увидит значение аргументов, и мы пройдем. Но основная проблема с этим подходом заключается в том, что запись AssertWasCalled (некоторое выражение лямбда) невозможна, потому что теперь в части Assert появляется ошибка, например ExpectaionViolationException не обрабатывается кодом пользователя

+0

Это не похоже на попытку ответить на этот вопрос. Вы хотели спросить об этом как отдельный вопрос? –

+0

это поддержка, которая дает мне свою точку зрения, что выше подход игнорирования аргументов неверно, потому что в приведенном выше случае мы вынуждаем тестовые примеры проходить. – Passenger

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