eproxus / meck

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

merge_expects together with passthrough seems does not set up the mocking #215

Closed zsoci closed 3 years ago

zsoci commented 3 years ago

version meck─0.9.0 (hex package)

It seems when merge_expects is used together with passthrough that will somehow not get handled. Alone, merge_expects works.

(met@fortytwo)1> mztest:good().
{mocked,{original,2}}
(met@fortytwo)2> mztest:bad().
{{original,1},{original,2}}
-module(mtest).
-export([fun_to_meck/1]).
fun_to_meck(A) ->
  {original, A}.
%%%%%%%%%%
-module(mztest).

-export([good/0,
         bad/0]).

good() ->
  ok = meck:new(mtest, []),
  run_test().

bad() ->
  ok = meck:new(mtest, [passthrough, merge_expects]),
  run_test().

run_test() ->
  ok = meck:expect(mtest, fun_to_meck, [{[1], mocked},
                                        {['_'], meck:passthrough()}]),
  Result = mtest:fun_to_meck(1),
  Result2 = mtest:fun_to_meck(2),
  ok = meck:unload(mtest),
  {Result, Result2}.
zsoci commented 3 years ago

Seems whe using passthrough the ExistingClauses already contains the passthrough and when adding the new clause it will be added after the existing one, so the passthroguh will always be found first and used, regardless of what the new clause tells. PR issued https://github.com/eproxus/meck/pull/216

zsoci commented 3 years ago

Well, the order of the expectation shall not be changed. A workaround is, when passthrough used with merge_expects, that after the meck:new(mod, fun, [passthrough, merge_expects]) call, a meck:delete(mod, fun, Arity, true) shall be called with all the arities that fun have in the mod and to be mocked. This cleans up the expectation set by the passthrough flag.

bad() ->
  ok = meck:new(mtest, [passthrough, merge_expects]),
  ok = meck:delete(mtest, fun_to_meck, 1, true),
  run_test().