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

Adam Lindberg adam@REDACTED
Tue May 24 11:32:52 CEST 2011


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<demeshchuk@REDACTED>  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
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list