You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
But then I have difficulty deleting expectations in case_cleanup: if I implement meck:delete/0, then it also removes expectations that were set up in fixture_setup and case_setup.
In particular passthrough and stub_all expectations.
So, I figure it'd be nice to be able to return an opaque term representing the current expectations at the end of case_setup. EUnit conveniently passes this to case_cleanup, where it could be restored with meck:reset_state/0.
This would save the slow meck:new and meck:unload on each case, but would guarantee that the state of the mocks was restored for the next test.
No, I mean the entire state. I'd like (if possible) to pickle and unpickle the entire state of all extant mocks -- stubs, mocks and fakes. Not necessarily expectations.
Let me take a step back here. The core problem is that meck:new is slow, so I'd like to avoid calling it for every case_setup.
However, the only way for case_cleanup to erase any mocks set up in the individual tests is by using meck:unload().
There is meck:delete, but that requires knowing which mocks to delete. So I implemented a meck_extras:delete_all. This required some deep poking around with sys:get_state, which is evil, so I can submit a PR for it, if that sounds like something that should be in core meck (where it won't need to be evil).
But that removes any [passthrough] or [stub_all] expectations, which can only be set in meck:new. And we're trying to avoid calling meck:new.
I guess, instead of saving/restoring state, meck:delete/0, meck:reset/0, meck:passthrough/1 and meck:stub_all/1 would be sufficient.
Oh, and the problem I found when attempting to write meck:stub_all(Mods) and meck:passthrough(Mods) is that, once you've called meck:new(Mod) there doesn't appear to be a way to get the exported functions any more.
When creating a mock, a new module is compiled (and the state is saved in the Meck process). When adding functions, passthroughs etc. the whole module is recompiled (since there is no way to add functions to an existing module in Erlang). This leads to that every new and expect call recompiles the module (which takes some time).
I suspect what you proposed would be equally slow to calling new, because everything will result in one or several recompilations anyway (new does some other things, like taking care of coverage etc., but that shouldn't be the major time consumption).
This requires recompiling the module on eachmeck:expect call. Would it be possible to add a way to add multiple expectations in one go, and only compiling once? Or maybe there is, and I missed it? Should I raise another issue for this?
Yeah, this is something I thought about as well, to have mock templates that compile everything in one go. Good point.
It's not possible at the moment, only different clauses for the same function at the same time. It's something I want to do for 2.0-something, to make the expects API more coherent and simpler (basically a tree structure of mod/func/clause, which would also make templating easier.
Activity
eproxus commentedon Jun 23, 2014
With state of the mocks, do you only mean the validation state (
meck:validate/1)?rlipscombe commentedon Jun 23, 2014
No, I mean the entire state. I'd like (if possible) to pickle and unpickle the entire state of all extant mocks -- stubs, mocks and fakes. Not necessarily expectations.
Let me take a step back here. The core problem is that
meck:newis slow, so I'd like to avoid calling it for everycase_setup.However, the only way for
case_cleanupto erase any mocks set up in the individual tests is by usingmeck:unload().There is
meck:delete, but that requires knowing which mocks to delete. So I implemented ameck_extras:delete_all. This required some deep poking around withsys:get_state, which is evil, so I can submit a PR for it, if that sounds like something that should be in core meck (where it won't need to be evil).But that removes any
[passthrough]or[stub_all]expectations, which can only be set inmeck:new. And we're trying to avoid callingmeck:new.I guess, instead of saving/restoring state,
meck:delete/0,meck:reset/0,meck:passthrough/1andmeck:stub_all/1would be sufficient.Then I could have:
rlipscombe commentedon Jun 23, 2014
Oh, and the problem I found when attempting to write
meck:stub_all(Mods)andmeck:passthrough(Mods)is that, once you've calledmeck:new(Mod)there doesn't appear to be a way to get the exported functions any more.eproxus commentedon Jul 1, 2014
Ok, I see what you mean, I think.
When creating a mock, a new module is compiled (and the state is saved in the Meck process). When adding functions, passthroughs etc. the whole module is recompiled (since there is no way to add functions to an existing module in Erlang). This leads to that every
newandexpectcall recompiles the module (which takes some time).I suspect what you proposed would be equally slow to calling new, because everything will result in one or several recompilations anyway (
newdoes some other things, like taking care of coverage etc., but that shouldn't be the major time consumption).eproxus commentedon Nov 21, 2016
Closing and documenting in the wiki instead: https://github.com/eproxus/meck/wiki#feature-ideas
Please comment here if you have information or requests to add, and/or want to discuss a PR or possible implementation proposal.
rlipscombe commentedon Nov 21, 2016
I have an alternative, related, suggestion:
We have a lot of fixture setup of the form:
This requires recompiling the module on each
meck:expectcall. Would it be possible to add a way to add multiple expectations in one go, and only compiling once? Or maybe there is, and I missed it? Should I raise another issue for this?eproxus commentedon Nov 21, 2016
Yeah, this is something I thought about as well, to have mock templates that compile everything in one go. Good point.
It's not possible at the moment, only different clauses for the same function at the same time. It's something I want to do for 2.0-something, to make the expects API more coherent and simpler (basically a tree structure of mod/func/clause, which would also make templating easier.