Когда использовать Mock v. Stub или нет?

Я читал о Mocks и Stubs, их различиях и использовании. Я все еще немного сбит с толку, но я думаю, что у меня есть суть.

Теперь я задаюсь вопросом о приложениях. Я вижу применение в создании "поддельных" объектов в тестовых сценариях, где реальные объекты слишком сложны, чтобы их можно было проверить, чтобы протестировать один аспект.

Но давайте рассмотрим мое приложение: я работаю над библиотекой вычислительной геометрии. Наша библиотека определяет точки, линии, сегменты линий, векторы, многоугольники и многогранники, а также множество других объектов и все обычные геометрические операции. Любой данный объект хранится в виде списка точек или направлений или объектов более низкого уровня. Но ни одному из этих объектов не требуется более нескольких миллисекунд для генерации.

Когда я тестирую эту библиотеку, имеет ли смысл где-нибудь использовать Mocks/Stubs?

Прямо сейчас мы просто используем конкретные тестовые случаи. Мы называем их заглушками, но я не думаю, что они соответствуют техническому определению заглушки. Как вы думаете, что лучше для этого? "TestCases"? "Примеры"?

SourceCode: https://bitbucket.org/Clearspan/geometry-class-library/src

Редактировать: Обратите внимание, что мы стремимся к неизменности во всех наших геометрических объектах, поэтому имеет смысл проверять только результаты операций, но не изменения состояния исходных объектов.

2 ответа

Решение

Принципиальная разница между макетом и заглушкой в ​​том, что макет может сделать ваш тест неудачным. Заглушка не может. Заглушка используется для обеспечения правильного выполнения программы. Это никогда не является частью утверждения.

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

Эта реализация (mock - assert, stub-flow) помогает нам сузить некоторые сценарии использования. Начать с более легкого...

издеваться

Как я уже упоминал, в утверждениях используются насмешки. Когда ожидаемое поведение вашего компонента заключается в том, что он должен общаться с этим другим компонентом - используйте mock. Всех тех

emailSender.SendEmail(email);
endOfDayRunner.Run();
jobScheduler.ScheduleJob(jobDetails);

можно только проверить, спросив ScheduleJobс такими и такими параметрами?"Это то место, где вы идете за макет. Обычно это будет единственный сценарий использования макета.

огрызок

С заглушкой это немного отличается. Использовать заглушку или нет -вопрос дизайна. Как только вы будете следовать обычному слабо связанному, основанному на внедрении зависимостей дизайну, в конечном итоге вы получите множество интерфейсов.

Теперь, когда в тесте, как вернуть значение из интерфейса? Вы либо заглушаете, либо используете реальную реализацию. У каждого подхода есть свои плюсы и минусы:

  • с созданными в библиотеке заглушками ваши тесты будут менее хрупкими, но могут потребовать дополнительной предварительной работы (настройка заглушек и т. д.)
  • с реальными реализациями, настройка уже выполнена, но когдаAngleизменения классаCoordinateSystemможет потерпеть неудачу... Желательно ли такое поведение или нет?

Это? Какой использовать? И то и другое! Все зависит от...

Единица работы

Мы добрались до финала и актуальной части проблемы. Каков объем вашего юнит-теста? Что такоеблок? МожноCoordinateSystemбыть отделенным от его внутренней работы и зависимостей (Angle, Point,Line) а можно ли их зарезать? Или, что более важно, они должны быть?

Вы всегда должныопределить, что является вашим подразделением. Это CoordinateSystemодин или, возможно,Angle, Line а также Pointиграть важную роль в этом? Во многих, многих случаях единица будет сформирована как методом, так и окружающей его экосистемой, включая доменные объекты, вспомогательные классы, расширения или иногда даже другие методы и другие классы.

Естественно, вы можете отделить их и заглушить, но потом... это действительно ваше устройство?

Как правило, используйте Mocks, когда вам нужно смоделировать поведение, и заглушки, когда единственное, что имеет значение в вашем тесте, - это состояние объекта, с которым вы общаетесь.

Принимая во внимание изменения, которые вы внесли в свое сообщение, когда вам нужно получить неизменяемый объект, используйте заглушку, но когда вам нужно вызывать операции, которые предоставляет объект, затем идите на макет, таким образом, вы не склонны к неудачным тестам из-за ошибки в реализации другого класса.

Другие вопросы по тегам