eproxus / meck

A mocking library for Erlang
http://eproxus.github.io/meck
Apache License 2.0
811 stars 231 forks source link

my_code_meck_original is not generated #170

Closed xianxu closed 7 years ago

xianxu commented 7 years ago

My company has its own build scripts, based on make, instead of rebar. So it's pretty hard to repro. I'm hoping to get some insight what might be wrong. Most possible is some environment setup.

So in an erl shell after loading some internal libraries (through some wrapper). The wrapper adds needed library search path etc. I noticed meck beam files are pulled in by a 3rd party dependency snappy.

I did the following. Here wlib is an internal module I want to mock.

rp(code:all_loaded()).

wlib's not loaded by default.

l(wlib).

rp(code:all_loaded()).

wlib loaded from some reasonable path, as:

... {wlib,"/home/whatsapp/wa/ebin/wlib.beam"}, ...

Now, let's try to mock wlib in passthrough mode. meck:new(wlib, [passthrough]). rp(code:all_loaded()).

wlib's replaced by mock, but the passthrough won't work as the wlib_meck_original's not generated.

{wlib,[]},

and if I then call a function on wlib, things blow up, complaining can't find the wlib_meck_original.

Reason for termination == {'module could not be loaded', [{wlib_meck_original,now_sec,[],[]}, {wlib,now_sec,[],[]}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,573}]}, {shell,exprs,7,[{file,"shell.erl"},{line,674}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,629}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,614}]}]}

Compare that with mocking string, mocking string in passthrough mode works as expected and string_meck_original's generated and loaded, shown by code:all_loaded().

meck:new(string, [unstick, passthrough]).

rp(code:all_loaded()).

... {string,[]}, ... {string_meck_original,[]}, ...

And string:strip(" test ") works as expected.

And tested with another internal module (not wlib) and meck works.

eproxus commented 7 years ago

Thanks for the bug report.

I'm not sure I follow along completely, did you forget to paste the output of the shell commands? You are loading the module wa but then try to mock the module wlib, should they be the same?

In general, Meck does not allow mocking modules which it cannot find (although it will discover modules on the path because Erlang loads them automatically). You can try to use the option non_strict to meck:new/2 to see if it makes a difference.

eproxus commented 7 years ago

Hi! Have you had time to try any of the suggestions? Do you still have the problem?

xianxu commented 7 years ago

Sorry for the late response. I updated OP. To your questions/suggestions:

So the clue seems to be: why would meck:new(string, [unstick, passthrough]). work but meck:new(wlib, [passthrough]). would not work.

eproxus commented 7 years ago

Yeah, it's very puzzling. Meck should throw errors for any failures to compile or load the original module. Is it compiled with debug_info?

eproxus commented 7 years ago

Close due to inactivity.