[erlang-questions] Mocking I/O calls - defining sequence of returns

Adam Lindberg <>
Wed May 25 18:16:28 CEST 2011


I've added something more lightweight to meck's official repo now in 
version 0.6 which might solve your problem. See the two commits:

https://github.com/eproxus/meck/commit/35de01e
https://github.com/eproxus/meck/commit/8d86012

It's the functions sequence/4 and loop/4 which works almost the same as 
expect/4 except that they return one value at a time from the list given 
as input (sequence will exhaust it and stick to the last element, and 
loop will loop the results infinitely).

Cheers,
Adam



Adam Lindberg wrote:
> Hi,
>
> Spurred by the discussion, I did take a look at implementing this in
> meck. There are a few alternatives to simulating state in mocks:
>
> * Using the process dictionary
> - Pros: fast, simple, easy to understand
> - Cons: not "thread safe", no transactions
>
> * Implement your own state in another process, used by the mock
> - Pros: fast, simple
> - Cons: can be made specific for the test case and thus needs less
> locking
>
> * Keeping state in the actual mock (a process in meck's case)
> - Pros: Can be made "thread safe"
> - Cons: slow (will lock process for each call to mock)
> You cannot do a mock with fun() -> timer:sleep(infinity) end,
> for example.
>
> The latter means that for a test program to be able to manipulate the
> mock (add expectations or get history) no code must be using the mock
> (since the mock process is blocked for the duration of the call to the
> mock, to be able to guarantee transactional state changes).
>
> I did a reference implementation of this and it got a bit messy in a few
> different edge scenarios, but it works.
>
> I did implement the synchronized state which has the cons described
> above. A simpler earlier version which I tested first had a much neater
> implementation but did not synchronize puts/gets between calls (similar
> to using the process dictionary, except that it was using the dictionary
> of the mock process instead).
>
> You can check out the latest implementation here:
> https://github.com/eproxus/meck/tree/put-get
>
> The branch adds meck:put/2 and meck:get/1 to be used inside mocks. A new
> option can be passed to meck:new/2 which initializes the dictionary:
>
> meck:new(mymod, [{dict, {a, 0}}]),
> meck:expect(mymod, test, fun() -> meck:put(a, meck:get(a) + 1) end),
> 0 = mymod:test(),
> 1 = mymod:test(),
> 2 = mymod:test(),
> % etc
>
> You can see the "breakage" created by looking at the uncommented test
> case. Performance has not been looked at at all.
>
> Cheers,
> Adam
>
>
>
> Tim Watson wrote:
>> On 23 May 2011 10:51, Dmitry Demeshchuk<> wrote:
>>> You can use meck and process dictionary combination, for example:
>>
>> That's a bit dangerous if the module under test gets called from
>> multiple processes though, which is often (perhaps even normally?) the
>> case. For very simple cases it might be ok though, as you say.
>> _______________________________________________
>> erlang-questions mailing list
>> 
>> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list