2013-08-02 2 views
0

Я пытаюсь найти лучший способ Assert, Должен ли я создавать объект с тем, что я должен вернуть, и проверить, что он равен ожидаемому результату?Единичные тесты: как утверждать? Утверждение результатов возвращено или что метод был вызван на макет?

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

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

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

Что утверждают все, что метод был вызван или утвердил результаты, которые были возвращены?

Конечно, не самая лучшая практика делать больше, чем 1 утверждать в единичном тесте, поэтому, возможно, ответ заключается в том, чтобы фактически утверждать результаты и что метод был вызван? Поэтому я бы создал 2 единичных теста, 1 для проверки результатов и 1, чтобы проверить, вызван ли метод.

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

Я был бы очень признателен за некоторые отзывы об этой области.

Заранее благодарен.

+0

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

ответ

1

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

Очень распространенный случай, когда в данный момент вы будете писать метод, который использует некоторую библиотеку HTTP для извлечения данных из REST API. Вы не хотите на самом деле делать HTTP-запросы в своих тестах, чтобы вы издевались над методом HTTP-клиента get(). С одной стороны, ваш макет может просто вернуть некоторые консервированную JSON ответ, как (с помощью RSpec в Ruby, в качестве примера):

http_mock.stub(:get).and_return('{result: 5}') 

Затем проверить, что вы можете правильно проанализировать это и вернуть некоторое правильное значение, основанное на ответ.

Вы также можете проверить, что вызывается метод HTTP get(), но более важно проверить, что он называется с правильными параметрами. В случае API ваш метод, вероятно, должен отформатировать URL-адрес с параметрами запроса, и вам нужно проверить, что он делает это правильно. Утверждение будет выглядеть примерно так (опять же с RSpec):

http_mock.should_receive(:get).with('http:/example.com/some_endpoint?some_param=x') 

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

0

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

  1. Действие (учитывая некоторые аргументы) дает правильный результат
  2. действие (учитывая некоторые аргументы) делает (или не делает) выбросить ожидаемое исключение
  3. Действие приводит к тому, что тестируемое устройство взаимодействует с зависимостями корректно.

Существуют разные требования, и в большинстве случаев можно протестировать несколько или все из них для метода (например, # 3, например, отсутствует, если вызываемый метод не имеет зависимостей, и т. д.)

Например: Класс, который переносит сторонний REST api для календаря бронирования, вероятно, будет зависеть от своего рода HTTP-клиента. Учитывая способ бронирования, мы можем придумать следующие тесты (среди прочего):

  • Попытка забронировать не открытое слот дает некоторые результаты, поясняющие, что время занято.
  • При отправке запроса на бронирование, запрос сериализации в Json и отправить в запросе теле запроса HTTP (prefereably с проверкой некоторых испытаний, что это для правильной конечной точки, а)

Первый тест больше сосредоточено на результатах, второе - на связи между вашими классами. Оба являются жизненно важными компонентами вашей системы. Мне нравится, чтобы тесты управляли моим дизайном, поэтому я, как правило, в конечном итоге пишу тесты для обоих сразу. Я нахожу, что если вы тестируете такие классы после лица, намного легче либо A) написать неряшливый мега-тест, который проверяет слишком много вещей и не очень помогает, либо B) просто опустить тестирование некоторых функций, в результате чего в отверстиях в вашем щите, что является регрессионным тестированием.

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

Смежные вопросы