"Короткое замыкание" пустых методов с Moq? - PullRequest
29 голосов
/ 30 июля 2009

моя команда недавно приняла решение использовать Moq в качестве нашей среды для насмешек из-за ее невероятной гибкости и хорошо читаемого синтаксиса. Поскольку мы новичок в этом, я спотыкаюсь о том, что кажется простыми вопросами - поиски (здесь, Google и т. Д.) Находят множество дискуссий о других нюансах Moq, но не обязательно, что я ищу, и несколько, казалось бы, связанных вопросов превратились в красную сельдь.

Мы тестируем класс, который имеет внешнюю зависимость (если быть точным, Amazon SimpleDb), но не хотим, чтобы наши тесты были связаны с наличием действующего соединения. Конкретный метод:

  • Применяет некоторую "бизнес" логику
  • Если это уместно, вызывает вызов в SDB через построенного нами провайдера, назовем его SaveItem()

Я хочу провести модульное тестирование таким образом, чтобы мы настроили требуемый контекст и обеспечили, чтобы SaveItem() был вызван, но таким образом, что SaveItem() действительно не вызывается (потому что A) поставщик SDB является ложным, что не полностью увлажнен и, вероятно, будет бомбить и Б) я не хочу платить за эту транзакцию сотни и тысячи раз).

При работе с методами, возвращающими значение, это было тривиально.

mockDb.Setup(d => d.GiveMeSomething()).Returns("Foo");

В случае, который я обрисовал выше, мой метод "SaveItem()" недействителен, и поэтому опция использования метода Returns() Moq недоступна. И хотя я могу настроить обратный вызов для проверки вызова SaveItem(), я, однако, не могу заставить его ничего не делать на самом деле.

Наивный / обнадеживающий, я думал, что будет работать следующее, но похоже, что метод все еще вызывается:

mockDb.Setup(d => d.SaveItem(It.IsAny<object>()));

Итак, вопрос на миллион долларов: что такое Moq следующего вымышленного кода?

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())).STOP_RIGHT_HERE();

1 Ответ

34 голосов
/ 30 июля 2009

Если метод SaveItem() является виртуальным или абстрактным, а вы не устанавливаете Callbase = true, то метод должен быть повторно реализован, чтобы макет ничего не делал.

Вы должны быть в состоянии сделать:

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())).Verifiable();

...  test here ...

mockDb.Verify();
...