I have library that uses HTTPoison for some functionality I need to test. To achieve this I am using Mox, which I believe is the universal mocking library for Elixir (even though there are others this one has the seal of approval of José Valim)
Everything is going fine, I define my mocks in the test_helpers.exs
:
ExUnit.start()
Mox.defmock(HTTPoisonMock, for: HTTPoison)
And I set up my dummy tests:
defmodule Alfred.Test.Http.Test do
use ExUnit.Case, async: true
import Mox
# Make sure mocks are verified when the test exits
setup :verify_on_exit!
describe "get" do
test "works on OK" do
HTTPoisonMock
|> get(:get, fn _ -> 1 end)
assert HTTPoisonMock.get(1) == 1
end
end
end
The problem here is I can't run them:
module HTTPoison is not a behaviour, please pass a behaviour to :for
Now, I know José Valim supports this ideology, thus everything we should mock should have a contract. But HTTPoison is not mine and it doesn't have one. So this brings me to the following question:
HTTPoison
uses the behaviour HTTPoison.Base
, so in this particular case, you are all set.
How can I mock 3rd libraries that don’t offer behaviours using
Mox
?
Usually, we do that with dependency injection. Whenever you need your 3rd-party, you simply pass it as a parameter and pass another module / mock in the test environment.