Мек ведет себя странно для нескольких смоделированных модулей
У меня есть следующий модуль
-module(bhavcopy_downloader).
-export([download/2]).
download(From, SaveTo) ->
{ok, {{Status, _}, _, Body}} = lhttpc:request(From, "GET", [], infinity),
case Status of
200 -> file:write(SaveTo, Body),
true;
_ -> false
end.
И следующие тесты для приведенного выше кода
file_download_test_() ->
{foreach,
fun() ->
meck:new(lhttpc)
meck:new(file, [unstick])
end,
fun(_) ->
meck:unload(file),
meck:unload(lhttpc)
end,
{"saves the file at specified location",
fun() ->
meck:expect(lhttpc, request, 4, {ok, {{200, "OK"}, [], <<"response">>}}),
meck:expect(file, write_file, fun(Path, Data) ->
?assertEqual(Path, "~/Downloads/data-downloader/test.html"),
?assertEqual(Data, <<"response">>)
end),
?assertEqual(true, bhavcopy_downloader:download("http://google.com", "~/Downloads/data-downloader/test.html")),
?assert(meck:validate(file))
end}]
}.
Когда я запускаю тесты, я получаю следующую ошибку (для краткости только часть ошибки вставлена ниже). Глядя на приведенную ниже ошибку, я чувствую, что файловый модуль не был смоделирован (или макет файлового модуля был переопределен, когда я установил другой макет, используя meck:new(lhttpc)
, Что может быть не так?
=ERROR REPORT==== 16-Feb-2013::20:17:24 ===
** Generic server file_meck terminating
** Last message in was {'EXIT',<0.110.0>,
{compile_forms,
{error,
[{[],
[{none,compile,
{crash,beam_asm,
{undef,
[{file,get_cwd,[],[]},
{filename,absname,1,
[{file,"filename.erl"},{line,67}]},
{compile,beam_asm,1,
[{file,"compile.erl"},{line,1245}]},
{compile,'-internal_comp/4-anonymous-1-',2,
[{file,"compile.erl"},{line,273}]},
{compile,fold_comp,3,
[{file,"compile.erl"},{line,291}]},
{compile,internal_comp,4,
[{file,"compile.erl"},{line,275}]},
{compile,'-do_compile/2-anonymous-0-',2,
[{file,"compile.erl"},{line,152}]}]}}}]}],
[{"src/lhttpc_types.hrl",
[{31,erl_lint,{new_builtin_type,{boolean,0}}},
{31,erl_lint,{renamed_type,bool,boolean}}]}]}}}
1 ответ
Это уловка 22 в Meck, вызванная тем, что Meck использует компилятор Erlang, который в свою очередь использует file
модуль. Когда Мек пытается перекомпилировать file
Модуль нуждается в file
модуль (через компилятор) и при этом вылетает.
На данный момент Мек не обрабатывает насмешки над файловым модулем. Ваша лучшая альтернатива - завернуть file
модуль вызывает в другом модуле и вместо этого смоделирует этот модуль.
(Теоретически возможно исправить это в Meck, используя вместо этого внутренние компоненты компилятора и сервера кода, например erlang:load_module/2
Однако это довольно сложно и должно быть хорошо спроектировано и протестировано)