2

I would like to be able to progressively set up a mock (using Meck), so that expectations for different calls are set in different test setup functions. I thought merge_expects might do the trick. But I am seeing unexpected results:

default__second_expect_overwrites_first_expect_test() ->
  meck:unload(),
  meck:new(womble, [non_strict]),

  meck:expect(womble, sleep, fun(8) -> ok end),
  meck:expect(womble, sleep, fun(24) -> comatose end),

  ?assertEqual(comatose, womble:sleep(24)),
  ?assertError(function_clause, womble:sleep(8)).

merge_expects__second_expect_has_no_effect_test() ->
  meck:unload(),
  meck:new(womble, [non_strict, merge_expects]),

  meck:expect(womble, sleep, fun(8) -> ok end),
  meck:expect(womble, sleep, fun(24) -> comatose end),

  ?assertError(function_clause, womble:sleep(24)),
  ?assertEqual(ok, womble:sleep(8)).

I know that I can use the following workaround, but it will uglify my tests:

workaround_test() ->
  meck:unload(),
  meck:new(womble, [non_strict]),

  meck:expect(womble, sleep, [{[8], ok}, {[24], comatose}]),
  ?assertEqual(comatose, womble:sleep(24)),
  ?assertEqual(ok, womble:sleep(8)).
MrBlueSky
  • 728
  • 6
  • 20

1 Answers1

2

This seems to be a "bug" related to using funs as expectations specifications (I think it was never supported in the first place, but in any case it is not documented clearly). As a workaround, you could use expect/4:

1> meck:new(womble, [non_strict, no_link, merge_expects]).
ok
2> meck:expect(womble, sleep, [24], comatose).
ok
3> womble:sleep(8).
** exception error: no function clause matching womble:sleep(8)
4> womble:sleep(24).
comatose
5> meck:expect(womble, sleep, [8], ok).
ok
6> womble:sleep(8).
ok
7> womble:sleep(24).
comatose
Adam Lindberg
  • 16,447
  • 6
  • 65
  • 85
  • Confirmed that fixes it - thanks Adam. The only place I know where I might still want to use `expect/3` is to set up a mock like this: `meck:expect(m2, mult42, fun(X) -> X*42 end).` – MrBlueSky Aug 08 '17 at 13:52
  • Merging function clauses is tricky, because they can have guards. This is not implemented in Meck currently. – Adam Lindberg Aug 08 '17 at 15:48