Цель издевательства - PullRequest
6 голосов
/ 16 июня 2009

Какова цель издеваться?

Я следовал некоторым учебникам ASP.NET MVC, в которых для тестирования используется NUnit, а для Mocking - Moq. Я немного неясен насчет насмешливой части этого.

Ответы [ 8 ]

16 голосов
/ 16 июня 2009

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

Это полезно, когда класс:

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

Это также облегчает проверку на наличие ошибок, поскольку вы создаете свой фиктивный объект, чтобы он возвращал и выдает ошибку, выдает исключение ...

Макет может записывать, как он был вызван (порядок вызовов функций, параметры), и это можно проверить с помощью теста. РЕДАКТИРОВАТЬ: Например: Тестируемый метод отправляет сообщение, например, IPC. Метод фиктивного объекта может записывать, сколько раз он был вызван, параметр, который он получил (то есть сообщение, которое будет отправлено). Затем тест может опросить фиктивный объект и установить количество отправленных сообщений, содержание сообщения ... Аналогично, фиктивный объект может записывать методы, которые вызываются в строке журнала, а тест может извлекать эту строку и утверждать ее.

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

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

7 голосов
/ 16 июня 2009

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

4 голосов
/ 16 июня 2009

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

  1. Прямой вывод - результат вызова метода
  2. Внутренние изменения - изменения класса во время вызова метода
  3. Косвенный вывод - тестируемый код вызывает другой класс

Основанное на состоянии тестирование - все о # 1 и # 2. # 1, глядя на результат, который дает вам метод. # 2 путем доступа к внутреннему состоянию объектов.

Это оставляет нас с # 3, для которого есть два пути, которые мы можем выбрать. Первый - с помощью Mock, а второй - с помощью Test Spy. Основное отличие состоит в том, что в Mock вы создаете ожидания перед выполнением тестируемого кода, а затем заставляете mock проверять их после, тогда как с помощью Test Spy вы выполняете тестируемый код и затем спрашиваете Test Spy, если произошли определенные действия.

Итак, чтобы подвести итог всего этого ... когда вы думаете о тестировании того, что делает класс, если вам нужно протестировать косвенный вывод (то есть вызов другого класса), именно здесь Mocking вступает в игру.

4 голосов
/ 16 июня 2009

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

3 голосов
/ 16 июня 2009

«Макет» - это термин, сильно перегруженный в кругах тестирования и TDD. См. Статью Мартина Фаулера Насмешки - это не заглушки . «Правильный» макет знает, какие значения он должен получить, и сообщает, когда он не получает того, что предполагалось; это позволяет вам выполнять тестирование взаимодействия вместо тестирования состояния - вы проверяете, что тестируемый класс передает правильные сообщения своим соавторам в правильной последовательности. Тестирование взаимодействия сильно отличается от обычного государственного тестирования и может быть трудно обдумать. Помня о том, что тестирование взаимодействия является предметом насмешек, они могут облегчить их понимание.

3 голосов
/ 16 июня 2009

Я новичок и в насмешках, но попробую. По моему опыту, у насмешек есть два основных преимущества:

  • Вы можете начать работу с объектами до того, как начнете писать реализацию. Вы можете определить интерфейс и использовать mocking для работы с интерфейсом в модульных тестах или даже в коде.
  • Mocking позволяет изолировать тестируемый объект в модульных тестах. С фиктивными объектами вы можете полностью контролировать любые объекты, с которыми взаимодействует тестируемый объект, и, следовательно, удаляя внешние зависимости из теста.
0 голосов
/ 04 апреля 2014

Отличный пример насмешки в реальном времени Берт F

Модульное тестирование

Представьте себе модульное тестирование для этой системы:

cook <- waiter <- customer

Как правило, легко представить тестирование низкоуровневого компонента, такого как cook:

cook <- test driver

Тест-водитель просто заказывает разные блюда и проверяет, что повар возвращает правильное блюдо для каждого заказа.

Сложнее проверить средний компонент, например официанта, который использует поведение других компонентов. Наивный тестировщик может проверить компонент официанта так же, как мы тестировали компонент повара:

cook <- waiter <- test driver

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

Так как это тест официанта, в идеале мы хотим проверить только официанта, а не повара. В частности, мы хотим убедиться, что официант правильно передает заказ клиента повару и правильно доставляет еду повара.

Под модульным тестированием подразумевается независимое тестирование модулей, поэтому лучшим подходом было бы изолировать тестируемый компонент (официант), используя то, что Фаулер называет тестовыми двойниками (манекены, заглушки, подделки, макеты) .

    -----------------------
   |                       |
   v                       |
test cook <- waiter <- test driver

Здесь тест-повар "в сговоре" с тест-драйвером. В идеале тестируемая система спроектирована таким образом, чтобы тестируемый повар мог легко заменить ( впрыскивается ) на работу с официантом без изменения производственного кода (например, без изменения кода официанта).

Макет объектов

Теперь тест готовить (test double) можно реализовать разными способами:

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

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

    -----------------------
   |                       |
   v                       |
mock cook <- waiter <- test driver

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

фиктивный объект заранее знает, что должно происходить во время теста (например, какие вызовы его методов будут вызваны и т. Д.), А фиктивный объект знает, как он должен реагировать (например, какое возвращаемое значение предоставить) , Насмешка покажет, отличается ли то, что действительно происходит, от того, что должно произойти. Пользовательский фиктивный объект может быть закодирован для ожидаемого поведения каждого тестового примера, но фреймворк стремится к тому, чтобы такая спецификация поведения была четко и легко указана непосредственно в тестовом примере.

Разговор вокруг фиктивного теста может выглядеть следующим образом:

тест-водитель до фальшивый повар : ожидайте заказ хот-дога и дайте ему этот фиктивный хот-дог в ответ

тест-водитель (выдавая себя за клиента) до официант : Хотелось бы хот-дог, пожалуйста
официант до ложный повар : 1 хот-дог, пожалуйста
Ложный повар до официант : оформить заказ: 1 хот-дог готов (дает фиктивного хот-дога официанту)
официант до тест-водитель : вот ваш хот-дог (дает фиктивного хот-дога тест-драйверу)

тестовый водитель : ИСПЫТАНИЕ УСПЕШНО!

Но поскольку наш официант новичок, это может произойти:

тест-водитель до фальшивый повар : ожидайте приказ хот-дога и дайте ему этот фиктивный хот-дог в ответ

тест-водитель (выдавая себя за клиента) до официант : Хотелось бы хот-дог, пожалуйста
Официант до Ложный повар : 1 гамбургер, пожалуйста
Ложный повар останавливает тест: Мне сказали ожидать заказа хот-дога!

тестовый драйвер отмечает проблему: ТЕСТ НЕ ПРОВЕРЕН! - официант изменил порядок

или

тест-водитель до фальшивый повар : ожидайте приказ хот-дога и дайте ему в ответ этот фиктивный хот-дог

тест-водитель (выдавая себя за клиента) до официант : Хотелось бы хот-дог, пожалуйста
Официант до Ложный повар : 1 хот-дог, пожалуйста
Ложный повар до Официант : Заказ: 1 хот-дог готов (дает фиктивного хот-дога официанту)
официант до тестовый водитель : вот ваш картофель фри (дает картофель фри из какого-то другого заказа для тестирования водителя)

тест-водитель отмечает неожиданную картошку фри: ТЕСТ НЕ ПРОВЕРЕН! официант вернул неправильное блюдо

Может быть трудно ясно увидеть разницу между фиктивными объектами и заглушками без контрастирующего примера на основе заглушек, но этот ответ уже слишком длинный: -)

Также обратите внимание, что это довольно упрощенный пример, и что фреймворк-фреймворки позволяют использовать довольно сложные спецификации ожидаемого поведения компонентов для поддержки всесторонних тестов. Для получения дополнительной информации имеется множество материалов о фиктивных объектах и ​​фреймворках.

0 голосов
/ 23 июня 2009

Еще один ответ:

  • Stub = поддельные объекты, чтобы иметь возможность запустить тест без полного реального контекста

  • Mock = поддельный объект для записи взаимодействия вашего компонента и проверки этих взаимодействий

Вы можете иметь несколько заглушек в одном тесте, но только один макет, потому что, если у вас есть более одного макета, вы, безусловно, тестируете более одной функции (и это побеждает цель принципа «тест с одной вещью»).

Чтобы выйти за рамки основ, Mocks - это скорее поведенческая проверка, чем традиционная проверка состояния теста, когда вы проверяете состояние вашего компонента после воздействия на него (Arrange, Act, Assert with Mocks, это больше Arrange, Act, Verify ):

Проверка состояния Assert.AreEqual (valueExpected, mycomponent.Property); Поведенческая проверка: myMock.WasCalled (MyMethod);

...