What causes a "not mocked" error when using meck (Erlang)? - erlang

I'm a meck (and Erlang) newbie and I'm struggling a bit with meck. I'm getting the following error:
=ERROR REPORT==== 27-Jan-2014::16:20:05 ===
Error in process <0.1825.0> with exit value: {{not_mocked,substatsDb},
[{meck_proc,gen_server,3,[{file,"src/meck_proc.erl"},{line,443}]},{meck_code_gen,exec,4,
[{file,"src/meck_code_gen.erl"},{line,147}]},{substats,loop,1,
[{file,"/Users/uyounri/gitsandbox/subpub/src/su...
At the beginning of my test I declare the module to be mocked:
meck:new(substats)
At the very end of my test the last thing I do is to unload the module that was mocked mocked:
meck:unload(substats)
The mocking seems to be working as expected until towards the end of the test when the above error is produced.
Thanks,
Rich
EDIT
Adding 2 ?debugFmt() lines seems to have fixed the problem; at least I no longer get the error. Here's the complete function that was modified:
stop(_) ->
meck:expect(substatsDb, stop, 1, fun(dbconn) -> ok end),
substats:stop(),
%% Note: this and the next ?debugFmt() calls prevent a meck
%% exit error. They both have to be present to prevent the error
?debugFmt("stop:~n", []),
meck:unload(substatsDb),
?debugFmt("stop: exit~n", []).

Have you tried adding the option passthrough when mocking the module?
meck:new(substatsDb, [passthrough])
Also, you are using the module "substatsDb" in the meck:expect call, but doing the meck:new for another module (substats), you should be doing everything for the same modules (new, expect, and unload)
hope it helps!

Related

<eof> expected near 'end'

I'm using these files in my gaming server, and every time I add a new player model, I get
[ERROR] lua/autorun/server/fastdlskins.lua:938: '<eof>' expected near 'end'
1. unknown - lua/autorun/server/fastdlskins.lua:0
I also get a similar error when I add an add-on to a different file
[ERROR] lua/autorun/server/workshopitems.lua:55: '<eof>' expected near 'end'
1. unknown - lua/autorun/server/workshopitems.lua:0
I usually just have to put an 'end' after the code, but I don't see what else I'm required to do. I don't have any loops running (I think), so I'm not closing any of those out. Not sure what to do.
As Egor said, remove the extra end at the end of the files.
end is only used to close blocks for functions and loops, like } in C-like languages. The end at the file is not closing anything, and is thus invalid syntax.

Erlang: why does -behaviour(supervisor) give me "undefined callback function" error?

When I try to compile an OTP supervisor module that starts like this:
-module(gridz_sup).
-behaviour(supervisor).
-export([start_link/0, start_child/2]).
-define(SERVER, ?MODULE).
yada, yada...
I get the following error:
gridz_sup.erl:9: Warning: undefined callback function init/1 (behaviour 'supervisor').
Can some kind soul point out the error of my ways?
Many thanks,
LRP
When implementing a behaviour call back module there is a number of mandatory call back functions that has to be defined and exported. If not you will get the warning as you saw. For the supervisor behaviour there is only one mandatory call back function init which takes one argument.

Meck behaving strangely for multiple mocked modules

I have following module
-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.
And following tests for the above code
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}]
}.
When I run the tests I get following error (only part of the error pasted below for brevity). Looking at the error below, I am kind of feeling that file module is not being mocked (or the mock of file module being overridden when I set the other mock using meck:new(lhttpc). What could be going wrong here?
=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}}]}]}}}
This is a catch 22 in Meck, caused by the fact that Meck uses the Erlang compiler, which in turns uses the file module. When Meck tries recompile the file module it needs the file module (through the compiler) and thus crashes.
As of this moment, Meck doesn't handle mocking the file module. Your best alternative is to wrap the file module calls in another module and mock this module instead.
(It is theoretically possible to fix this in Meck by using the internals of the compiler and the code server instead, for example erlang:load_module/2, however this is quite tricky and needs to be designed and tested well)

erlang_protobuffs doesn't decode as expected for messages with repeated field

I am working on a project that uses google proto buffers for internal data exchanges. It works fine as advertised, however it doesn't works as expected for messages with repeated fields in them. Here is an example:
Sample test.proto file:
message Test {
optional string t = 1;
}
message Tests {
repeated Test testsList = 1;
}
Generate erlang code:
1> protobuffs_compile:scan_file("test.proto").
=INFO REPORT==== 14-Sep-2012::16:38:25 ===
Writing header file to "test_pb.hrl"
=INFO REPORT==== 14-Sep-2012::16:38:25 ===
Writing beam file to "test_pb.beam"
ok
Generated test_pb.hrl:
-ifndef(TEST_PB_H).
-define(TEST_PB_H, true).
-record(test, {
t
}).
-endif.
-ifndef(TESTS_PB_H).
-define(TESTS_PB_H, true).
-record(tests, {
testslist = []
}).
-endif.
Encode:
5> test_pb:encode_tests({tests, [{test, <<"t">>}]}).
<<10,3,10,1,116>>
Decode:
6> test_pb:decode_tests(<<10,3,10,1,116>>).
{[{test,"t"}],undefined}
As in the above example, decoding doesn't give back the expected record tuple:
{tests, [{test, <<"t">>}]}
Has someone faced a similar issue before? Where am I missing the trick?
Any pointers and help will be greatly appreciated.
For versioning info, deps line from my rebar.config:
{protobuffs, "0.7.0", {git, "git://github.com/basho/erlang_protobuffs.git", {tag, "0.7.0"}}}
Just for an update.
0.7.0, 0.6.0 and HEAD were all giving me the same problem as described above.
After discussion on #riak IRC, I realized we need to use stable release marked by this commit hash: e0f5f6ea4c3dcb4e7b824496d2b48333fbd5a8c8 which solves the above issue.

Avoid NZEC error in Erlang in SPOJ

I've written code in Erlang, and I get the correct answer on my machine. But when I submit it on SPOJ it gives an NZEC (non zero exit code) error. I have used built-in functions like halt() and init:stop(), and their specification clearly says that they are used to avoid non-zero exit code error. But still I get the same error. How can I solve this problem?
EDIT The code as required by a comment:
-module(factorial).
-export([main/0]).
main() ->
{ok, [No_of_cases]} = io:fread("", "~d"),
loop(No_of_cases).
loop(0) ->
%init:stop();
halt(1);
loop(No_of_cases) ->
{ok, [Number]} = io:fread("", "~d"),
ResultFactorial = find_factorial(Number,1),
io:format("~p~n",[ResultFactorial]),
loop(No_of_cases-1).
find_factorial(0,Product) ->
Product;
find_factorial(Number,Product) ->
find_factorial(Number-1,Product*Number).
I got the answer. The trick is that your module name always has to be tested and the entry point should be function main . For example, after compilation it should be run as tested:main().

Resources