Я начал писать некоторые функции, помогающие проверять утверждения на картах.Eutit утверждает ошибку, сообщающую о неправильном модуле
Скажем, у меня есть следующая карта:
#{a => 0, b => 2}
И после того, как вызов функции в моей бизнес-логики я ожидаю карту, чтобы выглядеть следующим образом:
#{a => 1, b => 2}
Другими словами, я ожидаю,
- карту, чтобы иметь одинаковое количество ключей после обновления
- значения
a
изменяться от 0 до 1 - величина
b
неизменной
Я мог бы просто оставить этот тест для сопоставления с образцом, однако, если у меня есть большая карта с большим количеством ключей (и, возможно, даже много подмарок), неясно, где может быть проблема - по крайней мере, на это уходит какое-то время (возможно, некоторые значения, которые, как я ожидал, будут обновлены, - или, может быть, есть дополнительные ключи и т. д. , и т. д. - надеюсь, вы понимаете).
Так как начало, я придумал следующую вспомогательную функцию в моем модуле:
-module(asserts).
-include_lib("eunit/include/eunit.hrl").
maps_assert_map_has_updated_values(BaseMap, Updates, ResultingMap) ->
BaseMapKeys = lists:sort(maps:keys(BaseMap)),
ResultingMapKeys = lists:sort(maps:keys(ResultingMap)),
UpdatesKeys = lists:sort(maps:keys(Updates)),
BaseMapWithoutUpdates = maps:without(UpdatesKeys, BaseMap),
BaseMapKeysWithoutUpdates = lists:sort(maps:keys(BaseMapWithoutUpdates)),
ResultingMapWithoutUpdates = maps:without(UpdatesKeys, ResultingMap),
[
?_assertEqual(BaseMapKeys, ResultingMapKeys),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, Updates)},
{Key, maps:get(Key, ResultingMap)}) | Acc] end,
[],
UpdatesKeys
),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, true},
{Key, maps:is_key(Key, ResultingMap)}) | Acc] end,
[],
UpdatesKeys
),
lists:foldl(
fun(Key, Acc) -> [?_assertEqual({Key, maps:get(Key, BaseMapWithoutUpdates)},
{Key, maps:get(Key, ResultingMapWithoutUpdates)}) | Acc] end,
[],
BaseMapKeysWithoutUpdates
)
].
я называю это из другого модуля, который выполняется eunit:
-module(map_tests).
-include_lib("eunit/include/eunit.hrl").
simple_map_test_() ->
asserts:maps_assert_map_has_updated_values(
#{a => 0, b => 2},
#{a => 1},
#{a => 1, b => 3}).
И I получить следующее сообщение об ошибке:
asserts:30: maps_assert_map_has_updated_values...*failed* in function asserts:'-maps_assert_map_has_updated_values/3-fun-8-'/3 (test/asserts.erl, line 31)
**error:{assertEqual_failed,[{module,asserts},
{line,31},
{expression,"{ Key , maps : get (Key , ResultingMapWithoutUpdates) }"},
{expected,{b,2}},
{value,{b,3}}]}
Который является почти что я хочу, чтобы он сообщал о проблемном ключе и проблемных значениях на карте, однако сообщает об ошибке в модуле asserts
, хотя я заинтересован в том, чтобы увидеть фактический тест, который не удался, а не ссылку на утверждений. Я думал, что генераторы тестов были хороши для этого, но я не смог заставить это работать таким образом.
Есть ли способ, в котором я могу сделать eunit
отчет фактический тест модуля (map_tests
, функция/тест simple_map_test
линия X) вместо моего asserts
модуля?
Хм. Почему, однако, после того, как строка «в функции утверждает ...» ссылается на «test/asserts.erl, строка 31», нет ли линии «в вызове от», ссылающейся на номер строки в test/map_test.erl? Несомненно, проблема здесь заключается не в том, что модуль утверждений находится в верхней части трассировки стека, но нет ничего после вершины трассировки стека? – Michael
@Michael: В этом случае ваш вызов 'asserts' является последним вызовом в вашей тестовой функции. Erlang выполняет оптимизацию хвостовых вызовов, удаляя этот вызов из стека. Если после этого вы добавите еще одну значительную строку кода, вы сможете увидеть ее в своей трассировке стека. –
Ах, да, конечно, я вижу, хорошее место. – Michael