В чем смысл издевательства?
Я слежу за некоторыми учебными пособиями по ASP.NET MVC, в которых используется NUnit для тестирования и Moq для имитации. Я немного не понимаю, что это за насмешливая часть.
В чем смысл издевательства?
Я слежу за некоторыми учебными пособиями по ASP.NET MVC, в которых используется NUnit для тестирования и Moq для имитации. Я немного не понимаю, что это за насмешливая часть.
Цель имитации - изолировать тестируемый класс от других классов.
Это полезно, когда класс:
Это также упрощает проверку условий ошибки, поскольку вы создаете свой фиктивный объект, чтобы он возвращал и выдает ошибку, генерирует исключение ...
Макет может записывать, как он был вызван (порядок вызовов функций, параметры), и это можно проверить с помощью теста. РЕДАКТИРОВАТЬ: Например: метод, который вы тестируете, отправляет сообщение, например IPC. Метод фиктивного объекта может записывать, сколько раз он был вызван, параметр, который он получил (то есть сообщение, которое должно быть отправлено). Затем тест может опросить фиктивный объект и подтвердить количество отправленных сообщений, содержание сообщения ... Аналогичным образом, фиктивный объект может записывать методы, которые вызываются в строке журнала, и тест может извлекать эту строку и утверждать в теме.
Не злоупотребляйте фиктивными объектами: тестируйте поведение, а не реализацию, иначе модульные тесты будут слишком тесно связаны с кодом и будут нестабильными (нарушение рефакторинга).
Мок можно закодировать вручную или создать с помощью фреймворка имитации.
Мокинг позволяет изолировать тестируемый класс от его зависимостей. Как правило, вы создаете макет для каждой зависимости для тестируемого класса и настраиваете макет так, чтобы он возвращал ожидаемые значения. Затем вы предоставляете макет тестируемому классу вместо реальной копии класса, от которого зависит ваш тестируемый класс. Затем вы можете использовать фреймворк имитаций, чтобы проверить, были ли сделаны ожидаемые вызовы фиктивным объектам, чтобы убедиться, что ваш тестируемый класс работает правильно.
Он разработан, чтобы подшутить над отдельным экземпляром из групповой коллекции. Часто используется на нерегулярных сборах предметов.
Хотя под издевательством обычно понимается изоляция тестируемого класса, это не главное (заглушки для этого лучше). Вместо этого нам нужно посмотреть, что происходит, когда объекту приказывают сделать что-то, что является одной из трех вещей ...
Государственное тестирование - это все, что касается №1 и №2. # 1, глядя на результат, который дает вам метод. # 2 путем доступа к внутреннему состоянию объекта.
Это оставляет нас с № 3, для которого мы можем пойти двумя путями. Первый - с помощью Mock, а второй - с помощью Test Spy. Основное отличие состоит в том, что в Mock вы создаете ожидания перед выполнением тестируемого кода, а затем заставляете макет проверять их после, тогда как с Test Spy вы выполняете тестируемый код, а затем спрашиваете Test Spy, произошли ли определенные действия.
Итак, подведем итог ... когда вы думаете о тестировании того, что делает класс, если вам нужно протестировать косвенный вывод (он же вызов другого класса), именно здесь в игру вступает Mocking.
Я тоже новичок в насмешках, но я попробую это сделать. По моему опыту, у насмешек есть два основных преимущества:
«Мок» - это очень перегруженный термин в кругах тестирования и TDD. См. Статью Мартина Фаулера Моки - это не заглушки. «Правильный» макет знает, какие значения он должен получить, и сообщает вам, когда он не получает того, что было задумано; это позволяет вам проводить тестирование взаимодействия вместо тестирования состояния - вы проверяете, что тестируемый класс передает правильные сообщения своим сотрудникам в правильной последовательности. Тестирование взаимодействия сильно отличается от обычного государственного тестирования и может быть трудным для понимания. Помните, что тестирование взаимодействия - это суть имитаций, может облегчить их понимание.
Отличный пример издевательства в реальном времени от Берта Фа
Представьте себе модульное тестирование этой системы:
cook <- waiter <- customer
Обычно легко представить себе тестирование низкоуровневого компонента, такого как cook
:
cook <- test driver
Водитель-испытатель просто заказывает разные блюда и проверяет, что повар возвращает правильное блюдо для каждого заказа.
Сложнее протестировать средний компонент, например официанта, который использует поведение других компонентов. Наивный тестировщик может протестировать компонент официанта так же, как мы тестировали компонент готовки:
cook <- waiter <- test driver
Водитель-испытатель заказывал разные блюда и следил за тем, чтобы официант возвращал правильное блюдо. К сожалению, это означает, что этот тест компонента официанта может зависеть от правильного поведения компонента готовки. Эта зависимость еще хуже, если компонент повара имеет какие-либо недружелюбные к тестированию характеристики, такие как недетерминированное поведение (в меню есть сюрприз от шеф-повара как блюдо), множество зависимостей (повар не будет готовить без всего своего персонала) или много ресурсы (для некоторых блюд требуются дорогие ингредиенты или на приготовление уходит час).
Поскольку это тест официанта, в идеале мы хотим тестировать только официанта, а не повара. В частности, мы хотим убедиться, что официант правильно передает заказ от клиента повару и правильно доставляет еду от повара к клиенту.
Модульное тестирование означает независимое тестирование модулей, поэтому лучшим подходом было бы изолировать тестируемый компонент (официанта) с помощью what Фаулер вызывает тестовые двойники (манекены, заглушки, фейки, моки).
-----------------------
| |
v |
test cook <- waiter <- test driver
Здесь повар-испытатель находится «в сговоре» с водителем-испытателем. В идеале тестируемая система спроектирована таким образом, чтобы можно было легко заменить тестового повара (введенный) работать с официантом без изменения кода продукции (например, без изменения кода официанта).
Теперь тестовый повар (тестовый дубль) можно было реализовать по-разному:
См. статью Фаулера для получения более подробной информации о подделках, заглушках, макетах и манекенах, но для А теперь давайте сосредоточимся на имитационном поваре.
-----------------------
| |
v |
mock cook <- waiter <- test driver
Большая часть модульного тестирования компонента официанта сосредоточена на том, как официант взаимодействует с компонентом готовки. Подход, основанный на имитации, фокусируется на полном определении того, что является правильным взаимодействием, и обнаружении, когда оно идет наперекосяк.
Имитационный объект заранее знает, что должно произойти во время теста (например, вызовы его методов будут вызваны и т. Д.), А фиктивный объект знает, как он должен реагировать (например, какое возвращаемое значение предоставить). Имитация покажет, отличается ли то, что происходит на самом деле, от того, что должно произойти. Пользовательский фиктивный объект может быть закодирован для ожидаемого поведения каждого тестового примера, но фиктивный фреймворк стремится к тому, чтобы такая спецификация поведения была четко и легко указана непосредственно в тестовом примере.
Разговор вокруг имитационного теста может выглядеть так:
От тест-водителя до имитации повара: ожидайте заказа хот-дога и дайте ему в ответ этот пустышка.
тестовый водитель (изображающий из себя клиента) официанту: хотел бы хот-дог, пожалуйста
официант имитируйте готовку: 1 хот-дог, пожалуйста
имитируйте готовку официанту: закажите больше: 1 готовый хот-дог (дает пустышку официанту)
официант тест-драйверу: вот ваш хот-дог (дает пустышку хот-дог для тестирования водителя)тестовый драйвер: ТЕСТИРОВАНИЕ УСПЕШНО!
Но так как официант у нас новенький, могло случиться вот что:
От тест-водителя до имитации повара: ожидайте заказа хот-дога и дайте ему в ответ этот пустышка.
тестовый водитель (изображающий из себя клиента) официанту: хотел бы хот-дог, пожалуйста
официант имитирующий повар: 1 гамбургер, пожалуйста
имитирующий повар останавливает тест: Мне сказали ожидать заказ хот-дога! < / em>тестовый драйвер отмечает проблему: ТЕСТ НЕ ПРОШЕЛ! - официант изменил заказ
or
От тест-водителя до имитации повара: ожидайте заказа хот-дога и дайте ему в ответ этот пустышка.
тестовый водитель (изображающий из себя клиента) официанту: хотел бы хот-дог, пожалуйста
официант имитируйте готовку: 1 хот-дог, пожалуйста
имитируйте готовку официанту: закажите больше: 1 готовый хот-дог (дает пустышку официанту)
официант тест-водителю: вот ваш картофель фри (дает картофель фри из какой-то другой порядок тестирования драйвера)тест-водитель замечает неожиданный картофель фри: ТЕСТ НЕ ПРОШЕЛ! официант вернул не то блюдо
Может быть трудно четко увидеть разницу между макетными объектами и заглушками без контрастного примера на основе заглушек, чтобы пойти с этим, но этот ответ уже слишком длинный :-)
Также обратите внимание, что это довольно упрощенный пример, и что фреймворки имитации позволяют использовать некоторые довольно сложные спецификации ожидаемого поведения компонентов для поддержки всесторонних тестов. Для получения дополнительной информации есть много материала по фиктивным объектам и фреймворкам.
Еще один ответ:
Заглушка = поддельные объекты, чтобы иметь возможность запускать ваш тест без всего реального контекста
Mock = поддельный объект для записи взаимодействия вашего компонента и проверки этих взаимодействий.
У вас может быть несколько заглушек в одном тесте, но только один макет, потому что, если у вас более одного макета, вы определенно тестируете более одной функции (и это противоречит цели принципа «тест одно целое»).
Чтобы выйти за рамки основ, Mocks - это больше поведенческая проверка, чем традиционная проверка состояния теста, когда вы проверяете состояние вашего компонента после воздействия на него (Arrange, Act, Assert with Mocks, это больше Arrange, Act, Verify):
Проверка состояния Assert.AreEqual (valueExpected, mycomponent.Property); Поведенческая проверка: myMock.WasCalled (MyMethod);