vida tutorial sinonimo programacion lol lenguaje instalar como elixir

tutorial - Prueba de código asíncrono en elixir



elixir sinonimo (2)

Quiero probar una función que está utilizando Task.async

Para hacer que mi prueba pase, necesito hacerla dormir durante 100 ms antes de las afirmaciones, de lo contrario, el proceso de prueba se detiene antes de que se ejecute la tarea asíncrona.

¿Hay alguna manera mejor?

EDITADO, añadiendo ejemplos de código:

El código que me gustaría probar (aproximadamente):

def search(params) do RateLimiter.rate_limit(fn -> parsed_params = ExTwitter.Parser.parse_request_params(params) json = ExTwitter.API.Base.request(:get, "1.1/search/tweets.json", parsed_params) Task.async(fn -> process_search_output(json) end) new_max_id(json) end) end

Y la prueba que ya escribí (trabajando solo con la llamada a dormir)

test "processes and store tweets" do with_mock ExTwitter.API.Base, [request: fn(_,_,_) -> json_fixture end] do with_mock TwitterRateLimiter, [rate_limit: fn(fun) -> fun.() end] do TSearch.search([q: "my query"]) :timer.sleep(100) # assertions assert called TStore.store("some tweet from my fixtures") assert called TStore.store("another one") end end end


Como la pregunta es un poco vaga, daré la respuesta general aquí. La técnica habitual es monitorear el proceso y esperar el mensaje inactivo. Algo como esto:

task = Task.async(fn -> "foo" end) ref = Process.monitor(task.pid) assert_receive {:DOWN, ^ref, :process, _, :normal}, 500

Algunas cosas importantes:

  • El quinto elemento de la tupla es el motivo de salida. Estoy afirmando que la salida de la tarea es :normal . Cambie eso en consecuencia si está esperando otra salida.

  • El segundo valor en assert_receive es el tiempo de espera. 500 milisegundos suena como una cantidad razonable dado que actualmente tiene un sueño de 100 ms.


Cuando no puedo usar el enfoque de José que involucra assert_receive , uso un pequeño ayudante para hacer afirmaciones / suspensiones repetidamente, hasta que la afirmación pase o finalmente se agote.

Aquí está el módulo de ayuda

defmodule TimeHelper do def wait_until(fun), do: wait_until(500, fun) def wait_until(0, fun), do: fun.() def wait_until(timeout, fun) defo try do fun.() rescue ExUnit.AssertionError -> :timer.sleep(10) wait_until(max(0, timeout - 10), fun) end end end

Se puede usar así en el ejemplo anterior:

TSearch.search([q: "my query"]) wait_until fn -> assert called TStore.store("some tweet from my fixtures") assert called TStore.store("another one") end