开发者

Does ?assertException actually work with gen_fsm:startlink?

开发者 https://www.devze.com 2023-01-22 07:23 出处:网络
I have the following init method in a gen_fsm callback module (my_fsm): init(Args) when length(Args) =:= 2 ->

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号