2015-04-27 2 views
1

В ходе тестирования модуля рефакторинга в проекте я нашел несколько тестов, которые должны были быть неудачными, но преуспели по какой-то загадочной причине. После удаления ненужную кода и перемещения все в один метод, следующий минимальный пример до сих пор имеет оригинальное поведение:AssertWasCalled переходит на неиспользованную переменную

[Test] 
public void TestThatShouldFail() 
{ 
    // Arrange 
    var mock = MockRepository.GenerateStub<ISomething>(); 
    mock.Stub(wi => wi.SomeProperty).Return(MockRepository.GenerateStub<ISomeProperty>()); 
    mock.SomeProperty.Stub(t => t.SomethingElse).Return(new SomethingElse()); 
    ... 

    // Act  
    _foo.Foo(); 

    // Assert 
    mock.AssertWasCalled(wi => wi.SomeProperty.DoSomething()); 
} 

Переменная mock никогда не передается, подвергается или экспортируемого любым способом, который доступен в код, работающий в закон часть. Тем не менее, тест проходит, что должно означать, что метод DoSomething был вызван на SomeProperty переменной mock, что, очевидно, неверно.

Как это может произойти?

ответ

2

Этот код уже является результатом некоторого расследования, поэтому он содержит только строки, относящиеся к проблеме и ее решению.

Преступник является последней линией Упорядочить часть.

Как выясняется, Утверждайте линии не действительно ли метод DoSomething был вызван SomeProperty, но будет ли SomeProperty была доступна на mock! И мы на самом деле сделали это в последних Упорядочить линии, при выполнении на нем метода.

Я не могу найти официальную документацию для этого, поэтому могу только предположить, что он считает только первый уровень выражения в своем аргументе, поэтому не следует передавать выражения с несколькими уровнями доступа к члену (точки) до AssertWasCalled (или AssertWasNotCalled).

(Правильный способ проверить это будет mock.SomeProperty.AssertWasCalled(wi => wi.DoSomething()), но это был не нужен здесь.)

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