mustela
Hey all!
Im wondering if anyone have a good example or could help me understand how should I test an async task.
The closer I found was this question Testing Task Async, but it’s not that clear (at least for me).
So basically I have a module
defmodule Personas
def onboard(email) do
Task.start_link(fn -> process_onboard(email) end)
init_state()
end
end
init_state return a struct with some initial state. But the process_onboard function does a bunch of stuff, like reading data from external services and then create some records in the db (basically the persona).
I couldn’t find a way to make sure the task had run before actually testing things, so depending on how fast the task run I randomly get good or bad assertions (all the external services are mock). So I ended up adding a :timer.sleep(200) before checking for instance that the persona was onboarded.
result = Personas.onboard(@email)
# TODO: Find a better way to test async process
# if I dont use the sleep I could get error on the
# assertions. 200 milliseconds is enough to have
# the process completed
:timer.sleep(200)
persona = PersonaQuery.by_email(@email)
assert %{
first_name: "John",
last_name: "Doe"
} = persona
I would love to get rid of that sleep, so I would appreciate any thoughts/ideas around it.
Thanks a lot!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #hex
- #security










Marked As Solved- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
stefanchrobot
Have a look here.
Also Liked
josevalim
Unless you are using async/await, then the recommendation is to supervisor your tasks. Supervising your tasks will allow you to control shutdown, measure how many tasks are running, and so on. It also comes with the benefit of making the system easier to test.
mustela
Hey everyone! First of all, I have to thank you all for your awesome feedback. The fact that even @josevalim is answering to this “simple” question, expose how humble and awesome this community is…
About my particular problem, I took more time reading about supervisors and processes (Im kind of new in elixir) and it def makes more sense to use them. My brain is still trying to use other languages patterns, and not the specifics of the Elixir language. Lesson learned!
Again, thank you all for taking the time to try to help with my issue!
thiagomajesk
Hi @mustela!
I agree with @LostKobrakai’s response from the topic you linked: Testing Task Async - #2 by LostKobrakai. I would refactor the code to unit test only the abstractions that I have control over and by definition can properly be observed.
I’d say that if both functions inside
onboard/1don’t depend on each other, you should probably be unit-testing them separately. On the other hand, if they do and you’re not usingawaitto guarantee the task has run, you’ll probably have to deal with some sort of race condition.So the question in my head is if you should be using
asyncat this level of the abstraction. Perhaps you should make the code insideprocess_onboard/1async, but theprocess_onboard/1function itself returns something like{:ok | :error}.For example, this would be easier to test:
I’m quoting this because when we are talking about code that it’s difficult to test we can most of the time correlate with abstraction problems.
Update: I want to link this Kent Beck post because I feel this is relevant to the discussion. Hope that this helps you find out which abstractions of your application should be tested.