是吗?assertException实际上与gen_fsm一起使用:startlink?

时间:2010-10-29 09:26:49

标签: unit-testing erlang

我在gen_fsm回调模块(my_fsm)中有以下init方法:

init(Args) when length(Args) =:= 2 ->
   % do work with Args here
   {ok, my_state, InitialState}.

回调模块中没有其他init方法。

我想用eunit写一个单元测试,我断言用不包含两个元素的参数列表调用gen_fsm失败:

start_link_without_args_exits_test() ->
   ?assertException(exit, _, gen_fsm:start_link(my_fsm, [], [])).

然而,当测试运行时,eunit会跳过测试并显示以下消息:

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}]}

为什么测试没有“捕获”此错误并将其报告为通过测试?

1 个答案:

答案 0 :(得分:3)

异常实际发生在gen_fsm进程中。当调用init/1函数时,gen_fsm会捕获结果。如果它看到类似错误的内容,它会将错误发送回父级(通过proc_lib:init_ack/1-2),然后调用exit(Error)

因为你使用start_link并且没有捕获退出,所以你永远不会收到返回值 - 你只会崩溃。对于您的测试用例,您需要使用start或调用process_flag(trap_exit,true)以获取返回值,而不是仅在其他进程发生故障时崩溃。

然后你需要从

切换
?assertException(exit, _, gen_fsm:start_link(my_fsm, [], [])).

类似

?assertMatch({error,{function_clause,[{my_fsm,init,_} | _]}}, 
             gen_fsm:start_link(my_fsm, [], [])) 

为了让它运作良好。