I have the following init method in a gen_fsm callback module (my_fsm):
init(Args) when length(Args) =:= 2 ->
% do work with Args here
{ok, my_state, InitialState}.
There is no other init-method in the callback module.
I want to write a unit test using eunit where I assert that calling gen_fsm with an argument-list that does not contain two elements fails:
start_link_without_args_exits_test() ->
?assertException(exit, _, gen_fsm:start_link(my_fsm, [], [])).
However, when the test is run, eunit skips the test with the message:
undefined
*unexpected termination of test process*
::{function_clause,[{my_fsm,init,[[]]},
{gen_fsm,init_it,6},
{proc_lib,init_p_do_apply,3}]}{proc_lib,init_p_do_apply,3}]}开发者_JS百科
Why is it that the test does not "catch" this error and reports it as a passed test?
The exception actually happens in the gen_fsm
process. When the call to the init/1
function is made, gen_fsm
catches the result. If it sees something like an error, it will send the error back to the parent (through proc_lib:init_ack/1-2
) and then call exit(Error)
.
Because you use start_link
and are not trapping exit, you will never receive the return value -- you'll simply crash instead. For your test case, you'll need to either use start
or call process_flag(trap_exit,true)
in order to obtain the return value rather than just crashing when the other process goes down.
Then you'll need to switch from
?assertException(exit, _, gen_fsm:start_link(my_fsm, [], [])).
to something like
?assertMatch({error,{function_clause,[{my_fsm,init,_} | _]}},
gen_fsm:start_link(my_fsm, [], []))
In order to have it working well.
精彩评论