Al escribir código en Java, es muy útil abarcar composition y dependency injection para hacer posible y fácil hacer pruebas unitarias puras al burlar objetos colaboradores.¿Cómo hago la inyección de dependencia y me burlo en Erlang?
Me parece que hacer lo mismo en Erlang es menos sencillo y hace que el código sea más sucio.
Eso es probable que sea mi culpa, ya que soy bastante nuevo en Erlang y bastante adicto a JUnit, EasyMock e interfaces Java ...
Digamos que tengo esta estúpida función:
%% module mymod
handle_announce(Announce) ->
AnnounceDetails = details_db:fetch_details(Announce),
AnnounceStats = stats_db:fetch_stats(Announce),
{AnnounceDetails, AnnounceStats}.
Al probar la unidad mymod
, solo deseo probar que details_db
y stats_db
se invocan con los parámetros correctos y que los valores de retorno se usan correctamente. La capacidad de details_db
y stats_db
para generar el valor correcto se ha probado en otros lugares.
Para resolver el problema que podría refactorizar mi código de esta manera:
%% module mymod
handle_announce(Announce, [DetailsDb, StatsDb]) ->
AnnounceDetails = DetailsDb:fetch_details(Announce),
AnnounceStats = StatsDb:fetch_stats(Announce),
{AnnounceDetails, AnnounceStats}.
Y probar de esta manera (básicamente apagando las llamadas directamente en el módulo de prueba):
%% module mymod_test
handle_announce_test() ->
R = mymod:handle_announce({announce, a_value}, [?MODULE, ?MODULE, ?MODULE]),
?assertEqual({details,stats}, R).
fetch_details({announce, a_value}) ->
details.
fetch_stats({announce, a_value}) ->
stats.
Funciona, pero el código de la aplicación se ensucia y siempre tengo que llevar esa fea lista de módulos.
Yo he probado un par de bibliotecas simuladas (erlymock y (this other one) pero no estaba satisfecho.
¿Cómo se prueba su unidad de código Erlang?
Gracias!
Gracias Gordon, muy bien explicado. Todavía estoy tratando de cambiar al paradigma funcional. De todos modos, en este proyecto que estoy escribiendo (un rastreador de torrents), todas las llamadas se originan en desde la capa web y terminan en la base de datos, por lo que la mayoría de los módulos tienen o dependen de los efectos colaterales. Voy a probar el marco de prueba estándar. –
Good Erlang es tener muchas funciones pequeñas. Refactorice y divida su código en módulos de utilidad y se sorprenderá de lo poco que implica escribir en la base de datos. 15 - 25 líneas es una función larga en Erlang. Una función pura es aquella que toma un conjunto de parámetros, los calcula y simplemente devuelve un valor; debe tener muchos. –
En realidad, no estoy de acuerdo en que deba pasar a las pruebas de integración lo antes posible. Con los módulos parametrizados y la burla provista por erlymock, la función dada sería trivial de probar. Puede probarlo dentro del propio módulo burlándose de los dos módulos db durante la prueba. Puede usar este módulo en otras pruebas haciendo que los módulos db sean parámetros de su módulo. Cualquiera que mire burlarse de erlang debería echar un segundo vistazo a erlymock, el principal problema es la falta de documentación, por lo que realmente tiene que leer la fuente para aceptarlo. –