В EUnit Erlang утверждает, что функция была вызвана с помощью анонимной функции.
У меня есть код, который выглядит так:
-module(ca_data).
-export([delete_ca_data/1]).
% ...
delete_ca_data(N) when N < 1 -> ?NEGATIVE_ID_ERROR;
delete_ca_data(N) -> util_db_generic:delete_object(ca_data, N, fun(_) -> ok end).
% ...
И у меня есть тестовый код, который выглядит так:
wrap_meck(MockMod, MockArgs, F) ->
meck:new(MockMod, MockArgs),
try
F()
catch Ex ->
throw(Ex)
after
meck:unload(MockMod)
end.
delete_ca_data_test() ->
F = fun() ->
meck:expect(util_db_generic, delete_object, fun (_, _, _) -> ok end),
?assertEqual(?NEGATIVE_ID_ERROR, ca_data:delete_ca_data(-1)),
?assertEqual([], meck:history(util_db_generic)),
meck:expect(util_db_generic, delete_object, fun(_, _, _) -> ok end),
?assertEqual(ok, ca_data:delete_ca_data(1)),
?assertEqual(
[{self(), {util_db_generic, delete_object, [ca_data, 1, fun(_) -> ok end]}, ok}], % Uh-oh
meck:history(util_db_generic)
)
end,
wrap_meck(util_db_generic, [], F).
К сожалению,
util_db_generic:delete_object
функция вызывается функцией, созданной в тестируемом модуле.
Это создает некоторые проблемы при попытке подтвердить историю вызовов функций (например, в строке с пометкой «О-о»). Поскольку эта функция создается на месте (а указатель памяти фактически случайный), сложно утверждать, как должна выглядеть эта функция. Этот код не приводит к ошибкам компиляции. Однако утверждения никогда не будут возвращены как действительные, так как две разные функции утверждаются друг против друга (одна создана в
ca_data
модуль и один в тестовом примере). я пытался использовать
?assertMatch
и изменение
fun(_) -> ok end
выходит за
_
s, но я получаю эту ошибку компиляции в строке утверждения:
illegal pattern
Как я могу сопоставить эти результаты?
1 ответ
Хотя документация Erlang обычно хороша, это один из моментов, когда она подводит пользователя. В документации указано :
Evaluates Expr and matches the result against GuardedPattern, if testing is enabled. ... GuardedPattern can be anything that you can write on the left hand side of the -> symbol in a case-clause, except that it cannot contain comma-separated guard tests.
И документация для состояний :
Allowed in guard tests.
Тем не менее
self()
эта функция не может быть использована
assertMatch
макрос. Непонятно почему, но эксперимент это доказал.
РЕДАКТИРОВАТЬ 1:
Сюжет закручивается! Когда я редактирую тестовый код, чтобы он выглядел так:
delete_ca_data_test() ->
F = fun() ->
meck:expect(util_db_generic, delete_object, fun (_, _, _) -> ok end),
?assertEqual(?NEGATIVE_ID_ERROR, ca_data:delete_ca_data(-1)),
?assertEqual([], meck:history(util_db_generic)),
meck:expect(util_db_generic, delete_object, fun(_, _, _) -> ok end),
?assertEqual(ok, ca_data:delete_ca_data(1)),
Self = self(),
?assertEqual(
[{Self, {util_db_generic, delete_object, [ca_data, 1, _]}, ok}], % Uh-oh
meck:history(util_db_generic)
)
end,
wrap_meck(util_db_generic, [], F).
код компилируется и работает корректно! Для меня это неожиданный результат! Функция (которую можно использовать в сторожах) не разрешена, но возврат из функции разрешен! Интересно!