В чем смысл meck:validate?

Как новичок в meck, я собрал тест, который показывает различные функции. Однако я не могу понять, почему разработчик может вызывать meck:validate. Вот мой пример:

-module(meck_demo).

-include_lib("eunit/include/eunit.hrl").

validate_is_of_limited_use_test_() ->
    { foreach, fun setup_mock/0, fun cleanup_mock/1, 
      [fun validate_does_not_fail_if_a_function_is_not_called/0,
       fun validate_does_not_fail_if_a_function_is_called_with_wrong_arity/0,
       fun validate_does_not_fail_if_an_undefined_function_is_called/0,
       fun validate_does_fail_if_a_function_was_called_with_wrong_argument_types/0,
       fun validate_does_fail_if_expectation_throws_an_unexpected_exception/0 ]}.

validate_does_not_fail_if_a_function_is_not_called() ->
    meck:expect(womble, name, fun() -> "Wellington" end),   
    ?assert(meck:validate(womble)).

validate_does_not_fail_if_a_function_is_called_with_wrong_arity() ->
    meck:expect(womble, name, fun() -> "Madame Cholet" end),
    ?assertError(undef, womble:name(unexpected_arg)),
    ?assert(meck:validate(womble)).

validate_does_not_fail_if_an_undefined_function_is_called() ->
    ?assertError(undef, womble:fly()),
    ?assert(meck:validate(womble)).

validate_does_fail_if_a_function_was_called_with_wrong_argument_types() ->
    meck:expect(womble, jump, fun(Height) when Height < 1 -> 
                                ok
                              end),
    ?assertError(function_clause, womble:jump(999)),
    ?assertNot(meck:validate(womble)).

validate_does_fail_if_expectation_throws_an_unexpected_exception() ->
    meck:expect(womble, jump, fun(Height) -> 42 = Height end),
    ?assertError({badmatch, 999}, womble:jump(999)),
    ?assertNot(meck:validate(womble)).   

setup_mock() ->
    meck:new(womble, [non_strict]).

cleanup_mock(_SetupResult) ->
    meck:unload(womble).

Что мне не хватает?

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


person MrBlueSky    schedule 07.04.2017    source источник


Ответы (1)


Вам удалось найти почти каждый случай, не охватываемый валидацией (добавлена ​​лучшая документация в 10c5063 ).

Проверка может обнаружить:

  • Когда функция была вызвана с неправильными типами аргументов (function_clause)
  • Когда было выбрано исключение
  • Когда было выбрано и ожидалось исключение (через meck:exception/2), которое по-прежнему приводит к тому, что true возвращается из meck:validate/1

Проверка не может обнаружить:

  • Когда вы не вызвали функцию
  • Когда вы вызвали функцию с неправильным количеством аргументов
  • Если вы вызвали неопределенную функцию

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

person Adam Lindberg    schedule 07.04.2017
comment
Спасибо, Адам, это очень полезно. Объяснение, которое вы дали относительно того, почему Meck не может обнаружить определенные злоупотребления, имеет смысл. Я обновил свой вопрос, чтобы отразить приведенные вами примеры. В тех случаях, когда проверка не проходит не удается, тест все равно демонстрирует ошибку (assertError). Так что я до сих пор не очень понимаю, почему кодер вообще вызывает валидацию. - person MrBlueSky; 10.04.2017
comment
Я согласен, что его использование ограничено. Одним из вариантов использования может быть то, что ваш тестируемый код может не давать сбоев, а внутренне перехватывать слишком много исключений. В этом случае, если ваш макет вызывается неправильно, вы можете использовать Meck, чтобы узнать, должен ли ваш код дать сбой или нет. - person Adam Lindberg; 10.04.2017