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?