13
ERLYMOCK TUTORIAL By chaoslawful

Erlymock tutorial

Embed Size (px)

Citation preview

Page 1: Erlymock tutorial

ERLYMOCK TUTORIAL

By chaoslawful

Page 2: Erlymock tutorial

What’s ErlyMock?

A mocking framework for Erlang Mock any method in any modules Various features:

Argument verification Call order verification

Divergence: Sheyll’s: http://erlymock-site.sourceforge.net Nialscorva’s: https://github.com/nialscorva/

erlymock

Page 3: Erlymock tutorial

Looking down from 30,000ft high Sheyll’s version:

M = em:new(),

em:strict(M, module, function, [arg, em:any()], {return, ok}),

em:stub(M, module, function2, [1, 2, 3], {function, fun (_) -> throw(myerror) end}),

% replaying phase

em:replay(M),

% test

?assertMatches(ok, module:function(arg, anything)),

?assertThrow(myerror, module:function2(1, 2, 3)),

em:verify(M).

Page 4: Erlymock tutorial

Looking down from 30,000ft high

Nialscorva version:

erlymock:start(),erlymock:strict(module, function, [arg, '_'], [{return, ok}]),erlymock:stub(module, function2, [1, 2, 3], [{throw, myerror}]),

% initializeerlymock:replay(),

% test?assertMatches(ok, module:function(arg, anything)),?assertThrow(myerror, module:function2(1, 2, 3)),erlymock:verify().

Page 5: Erlymock tutorial

ErlyMock(sheyll’s) Funcs

em:new/0 – Create new mock expectation instance (gen_fsm proc) em:strict/4,5 – Strict call expectation

Strict calls must occur once for each, and in the order of declarations. em:strict/4 mocked func always return atom ‘ok’ em:strict/5 can specify return value with:

{return, V} – Mocked func return value V {function, F} – Mocked func call function F, and use its return value as return value

em:stub/4,5 – Stub call expectation Stub calls can occur any times, and in any order. Mocked func return value can be specified as above.

em:replay/1 – Finish expectation programming phase, start replaying phase Must be called before actual test code and after expectation declarataions.

em:verify/1 – Verify expectations, and destroy mock instance Must be called after test code.

em:any/0 – Return wildcard argument verifier em:nothing/2 – Demand no funcs in the specified module can be called

Page 6: Erlymock tutorial

ErlyMock(nialscorva’s) Funcs erlymock:start/0 – Start mock service (gen_server proc) erlymock:strict/3,4 – Strict call expectation

Strict calls must occur once for each, and in the order of declarations. erlymock:strict/3 mocked funcs always return atom ‘ok’ erlymock:strict/4 can specify return value with (put in a list):

{return, V} – Mocked func return value V {throw, V} – Mocked func call erlang:throw/1 with reason V {exit, V} – Mocked func call erlang:exit/1 with reason V {error, V} – Mocked func call erlang:error/1 with reason V {function, F} – Mocked func call function F, and use its return value as return value

erlymock:replay/0 – Finish expectation programming, start replaying phase Must be called before actual test code and after expectation declarataions.

erlymock:verify/0,1 – Verify expectations, and destroy mock instance Must be called after test code. erlymock:verify/1 can specify timeout for verification process.

Page 7: Erlymock tutorial

ErlyMock(nialscorva’s) Funcs, cont. erlymock:stub/3,4 – Stub call expectation

Stub calls can occur any times, and in any order. Mocked func return value can be specified as above. Can retrict minimum and maximum invocation times of

mocked func with options: {min_invocations, Count} – Specify min invocation times,

default to 0. {max_invocations, Count} – Specify max invocation times,

default to infinity. erlymock:o_o/3,4 – Out of order call expectation

Out of order calls are simply stub calls with min_invocation=max_invocation=1, i.e. call exactly once in any order.

Mocked func return value can be specified as above.

Page 8: Erlymock tutorial

Mock example – Missile Launcher Two layer:

launch_console – Interact with missile operator launcher – Called by console, control missile

hardware Need test launch_console:launch/0, it must comply

to the following restrictions: Must call launcher:confirm/0 first If launcher:confirm/0 return false, nothing to do If launcher:confirm/0 return true, call launcher:launch/2 with fixed coordinate

Time must be retrieved through launcher:time/0

Page 9: Erlymock tutorial

Mock example - Missile Launcher

Mocking test cases:mock_test1() ->

M = em:new(),

em:stub(M, launcher, time, [], {function, fun () -> Old = case get(mock_time) of undefined -> 0; V -> V end, put(mock_time, Old+1), Old end}),

em:stub(M, launcher, launch, [em:any(), em:any()], {function, fun ()->throw(should_not_happen) end}),

em:strict(M, launcher, confirm, [], {return, false}),

em:replay(M),

launch_console:launch(),

em:verify(M).

mock_test2() ->

Lat = 33.8, Lon = 45.0,

M = em:new(),

em:stub(M, launcher, time, [], {function, fun () -> Old = case get(mock_time) of undefined -> 0; V -> V end, put(mock_time, Old+1), Old end}),

em:strict(M, launcher, confirm, [], {return, true}),

em:strict(M, launcher, launch, [Lat, Lon]),

em:replay(M),

launch_console:launch(),

em:verify(M).

Page 10: Erlymock tutorial

Commons between impls

Use beam code hot swapping mechanism to implement module mocking. See compile:forms/1, code:purge/1, code:delete/1 and erlang:load_module/2

Note: Mocking must happened for entire module, restricted by

this impl method. Mocking partial funcs in a module is netiher possible nor desirable.

Can’t mock the same module in parallel running test cases.

Mocked funcs are generated on the fly in memory, according to declared expectations. See erl_syntax module

Page 11: Erlymock tutorial

Sheyll’s compare to Nialscorva’s

Pros Can recover coverage data after mocking finished Shortter module name ;-) Support multiple expectation instance (can parallel run test cases if

using different mock module) Implemented in gen_fsm, cleaner than Nialscorva’s With ‘nothing’ expectation With ‘any’ arg verifier, express wildcard matching in cleaner way

Cons Can’t restrict stub call min/max invocation times No out of order call expectation (due to above reason) No express way to specify throw/exit/error return value No built-in TCP server mocking support (can be done with self-

connected socket pair) No short-cut wildcard arg verifier ‘_’ (but also without its ambiguity) Use maven instead of rebar as building tools, not very erly…

Page 12: Erlymock tutorial

Personal thoughts

Neither impl are good enough… For now, recommend Sheyll’s impl prior

to Nialscorva’s We can contribute our efforts to make

Sheyll’s impl better, it’s not so hard. Sheyll’s impl: 641 lines Nialscorva’s impl: 843 lines

Page 13: Erlymock tutorial

Q&A

That’s all, folks!