Fl4m3Ph03n1x
Background
I am working in a project that uses Mock for testing. However I need to run a specific scenario, where the output of a function depends on the number of times said function is called.
I don’t think Mock supports this, so I am trying to find out a way to conduct this test.
Code
In this test I have a Storage module which I want to mock (it has side effects and is a boundary).
In the test, I call a function get, which the first time returns nil, then I save some data with save and then I call get again.
test_with_mock "returns OK when products list is saved into storage", Storage, [],
[
save: fn _table, data -> {:ok, data} end,
get: fn
_table, _seats_number -> {:ok, nil} # first call it returns nil
_table, _seats_number -> {:ok, [1]} # second call should return some data
end
] do
# Arrange
products = [
%{"id" => 1, "gems" => 4},
%{"id" => 3, "gems" => 4},
]
products_table = :products
# Act & Assert
actual = Engine.save_products(products)
expected = {:ok, :list_saved_successfully}
assert actual == expected
# First call to get returns nil because the table is empty.
# Then we save something into it.
assert_called Storage.get(products_table, 4)
assert_called Storage.save(products_table, {4, [1]})
# Second call should return the product previously saved
# But the mock only returns nil
assert_called Storage.get(products_table, 4)
end
The issue here is that since there is no counter, I don’t have a way of returning a different output depending on the number of calls a function was called.
To be fair, Mock does offer a way to returns different outputs when the input is different. However, this is not the case. The input is the same, the only different is the number of invocations.
Question
How can I achieve my goal using Mock?
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










Showing Posts 1 to 2- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
LostKobrakai
You could use the process dict for storing how many times the function was called yet. Given Mock doesn’t support async tests anyways you shouldn’t get into trouble with that.
brettbeatty
I think for what you’ve describe the process dictionary is a good way to go
Something I’ve done in the past is send messages to
self()containing what I want the mock function to return.So in my test I would do something like this:
And then my mock function would look something like this:
I often do this without a mocking library and send messages back, using assert_received/2 in place of
assert_called/1or the like. It also lets me use refs instead of:mock_return.