Подтвердить что ты не робот

Как использовать Mocks?

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

Но теперь я начинаю думать об этом по-другому. Мне интересно, эффективны ли Mocks для полной изоляции тестируемого метода от чего-либо вне себя. Образ, который приходит на ум, - это фон, который вы используете при рисовании. Вы хотите, чтобы краска не обходила все. Я только тестирую этот метод, и я только хочу знать, как он реагирует на эти фальшивые внешние факторы?

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

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

4b9b3361

Ответ 1

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

Цель mocks заключается в unit test вашем коде в изоляции зависимостей, чтобы вы действительно могли проверить фрагмент кода на уровне "единицы". Проверяемый код - это реальная сделка, и каждая другая часть кода, на которую он опирается (через параметры или инъекцию зависимостей и т.д.), Является "Mock" (пустая реализация, которая всегда возвращает ожидаемые значения при вызове одного из его методов).

Москиты могут казаться утомительными сначала, но они делают Unit Testing намного проще и надежнее, когда вы получаете возможность использовать их. Большинство языков имеют библиотеки Mock, которые делают насмешливым относительно тривиально. Если вы используете Java, я рекомендую мой личный фаворит: EasyMock.

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

Ответ 2

Не спускайтесь по темному пути, Мастер Люк.:) Не издевайтесь над всем. Вы могли бы, но не должны... вот почему.

  • Если вы продолжаете тестировать каждый метод в отдельности, у вас есть сюрпризы и работа, вырезанные для вас, когда вы объединяете их вместе с BIG BANG. Мы строим объекты так, чтобы они могли работать вместе, чтобы решить большую проблему. Сами по себе они несущественны. Вы должны знать, работают ли все соавторы как ожидаемые.
  • Mocks делает тесты хрупкими, вводя дублирование. Да, я знаю, что это звучит тревожно. Для каждого макета, ожидающего установки, есть n мест, где существует сигнатура вашего метода. Фактический код и ваши макетные ожидания (в нескольких тестах). Изменить реальный код проще... обновление всех макетных ожиданий утомительно.
  • Тест теперь посвящен информации об инсайдерской реализации. Таким образом, ваш тест зависит от того, как вы решили реализовать решение... плохо. Тесты должны быть независимыми, которые могут быть удовлетворены несколькими решениями. У меня должна быть свобода просто нажать delete на блоке кода и переопределить без, чтобы переписать набор тестов.. поскольку требования остаются неизменными.

Чтобы закрыть, я скажу: "Если он сходит с ума, как утка, ходит, как утка, то, возможно, это утка". Если он чувствует себя не так, возможно, это так. * Используйте mocks для абстрагирования проблемных детей, таких как операции ввода-вывода, базы данных, сторонние компоненты и т.д. Как соль, некоторые из них необходимы.. слишком много и: x *
Это священная война, основанная на тестировании на основе Iteraction. Googling даст вам более глубокое понимание.

Уточнение: я нанесу какое-то сопротивление w.r.t. интеграционные тесты здесь:) Итак, чтобы прояснить мой стенд.

  • Mocks не фигурирует в области "Приемочные испытания" /Интеграция. Вы найдете их только в мире тестирования модулей, и это мое внимание здесь.
  • Приемочные тесты различны и очень важны, а не принижают их. Но модульные тесты и тесты приемки различны и должны быть разными.
  • Все сотрудники в составе компонента или пакета не обязательно должны быть изолированы друг от друга. Подобно микро-оптимизации, которая является Overkill. Они существуют, чтобы решить проблему вместе.. сплоченность.

Ответ 3

Да, я согласен. Я вижу насмешливую, как иногда больную, но часто необходимую, чтобы ваши тесты действительно стали тестами unit, т.е. Тестируется только самая маленькая единица, с которой вы можете сделать свой тест. Это позволяет устранить любые другие факторы, которые могут потенциально повлиять на результат теста. В итоге вы получаете гораздо больше небольших тестов, но становится намного проще работать там, где проблема с вашим кодом.

Ответ 4

Моя философия заключается в том, что вы должны написать тестовый код для соответствия тестам,
не писать тесты, чтобы соответствовать коду.

Что касается сложности, я считаю, что тесты должны быть просты в написании, просто потому, что вы пишете больше тестов, если они есть.

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

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

Ответ 5

Да, это недостаток тестирования с помощью mocks. Есть много работы, которую вам нужно положить, чтобы она казалась зверской. Но в этом суть модульного тестирования. Как вы можете тестировать что-то изолированно, если вы не издеваетесь над внешними ресурсами?

С другой стороны, вы издеваетесь над медленными функциями (такими как базы данных и операции ввода-вывода). Если тесты выполняются быстрее, это будет держать программистов счастливыми. Нет ничего более болезненного, чем ждать очень медленных тестов, для завершения работы требуется более 10 секунд, в то время как вы пытаетесь реализовать одну функцию.

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

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

Ответ 6

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

Когда кто-то пытается зарегистрироваться, CheckInUi отправляет объект CheckInInfo в объект CheckInMediator, который проверяет его с помощью CheckInValidator, то, если это нормально, он заполняет объект домена с именем Транзакция с помощью CheckInInfo с помощью CheckInInfoAdapter, затем передает Сделку для экземпляра ITransactionDao.SaveTransaction() для сохранения.

Я сейчас пишу несколько автоматических тестов интеграции, и, очевидно, CheckInUi и ITransactionDao - это окна для внешних систем, и это те, которые нужно издеваться. Однако, чей, чтобы сказать, что в какой-то момент CheckInValidator не будет звонить веб-службе? Вот почему при написании модульных тестов вы предполагаете, что все, кроме определенных функций вашего класса, является внешней системой. Поэтому в моем unit test CheckInMediator я издеваюсь над всеми объектами, с которыми он разговаривает.

РЕДАКТИРОВАТЬ: Гишу технически корректен, не все должно насмехаться, я, например, не считаю mock CheckInInfo, поскольку это просто контейнер для данных. Однако все, что вы могли бы увидеть как внешнюю службу (и это почти все, что преобразует данные или имеет побочные эффекты), должно быть издевательством.

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

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

Действительно потратьте время, чтобы изучить его правильно, в тот день, когда я понял, что Мокс был огромным a-ha моментом. Объедините его с инверсией контейнера управления, и я никогда не вернусь.

С одной стороны, один из наших ИТ-специалистов просто вошел и дал мне бесплатный ноутбук!

Ответ 7

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

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

Ответ 8

Мошки были изобретены частично ответить на вопрос: Как бы вы unit test объекты, если у них не было геттеров или сеттеров?

В наши дни рекомендуется практиковать, чтобы имитировать роли не объекты. Используйте Mocks как средство разработки, чтобы говорить о сотрудничестве и разделении обязанностей, а не как "умные заглушки".

Ответ 9

Макетные объекты: 1) часто используются как средство для изолирования тестируемого кода, но 2) как уже отмечалось, keithb важны для " focus о взаимоотношениях между сотрудничающими объектами". В этой статье приводятся некоторые сведения и история, связанные с темой: Проект, управляемый ответственностью с помощью Mock Objects.