Reputation: 15736
There are probably lots of similar questions here but I still don't understand how it's done.
Let's say I have the following trivial module:
defmodule ModuleOne do
def do_something(argument) do
argument
|> do_first_thing()
|> do_second_thing()
|> ModuleTwo.do_something()
end
end
Now, I have ModuleTwo
covered with tests so it doesn't make sense to duplicate that testing logic. Also it's not Twitter API
module or something of the kind so I dont think it's a good idea to come up with a compile-time mock module ( as far as I can see, it's a good idea in case cases, like HTTP calls but doing that for every external module call will obviously turn into a mess ) and also I don't want to pass a function as an argument just for the sake of testing ( especially if I have calls to multiple external modules ) because it messes up the interface with unnecessary things.
Also people suggest not to use mocks, like the meck
library, which is the most obvious decision here, but I don't understand why ...
Anyway, what would be a good way to test this module considering all the suggestions above?
Thank you
Upvotes: 1
Views: 131
Reputation: 12127
I agree with Lukáš Doležal. Don't call ModuleTwo.do_something()
in ModuleOne.do_something()
. The ideal is to have small functions that perform one task well. So, ideally you would do ModuleOne.do_something() |> ModuleTwo.do_something()
instead.
However, sometimes the things that are ideal are not practical. Without context here we won't know. If that is the case, and you really want to cover everything with zero duplication, then there is a compromise that might work for you:
defmodule ModuleOne do
def foo(bar) do
bar
|> first()
|> second()
|> ModuleTwo.foo()
end
end
defmodule ModuleOne do
def foo(bar), do: do_foo(bar) |> ModuleTwo.foo()
def do_foo(bar) do
bar
|> first()
|> second()
end
end
And then just test ModuleOne.do_foo/1
instead of ModuleOne.foo/1
Upvotes: 0
Reputation: 289
My suggestions would be:
1) Don't call the ModuleTwo
in ModuleOne
at all. Then test only the transformation before. And move the ModuleTwo
call to the caller code or other "integration" module. Then test the caller code/integration model separately on integration level.
2) Use meck
to test that ModuleTwo
has been called with the argument you expect. But it is then similar to 1) as it practically test the 2 transformation steps.
Upvotes: 1