1

Background

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)

Problem

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

Mock Contracts, not implementations

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:

  • How can I mock 3rd libraries that don't offer behaviours using Mox ?
Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266

1 Answers1

2

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.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • I can't use `HTTPoison.Base` because I want to mock the get, post, put ... functions, and not the strict ones they allow. I could dependency inject the module as a dummy object, but then what's the point of Mox? – Flame_Phoenix Jan 15 '19 at 09:26
  • I doubt I follow. Have you clicked the links I provided? What do you mean by “strict ones they allow”? `HTTPoison` is literally _an alias_ for `HTTPoison.Base`. Here are e.g. [`get` callbacks](https://github.com/edgurgel/httpoison/blob/master/lib/httpoison/base.ex#L89-L92). Also, the main point of `Mox` is to mock _your own code_. – Aleksei Matiushkin Jan 15 '19 at 09:55
  • Ahh, I missed those. Thanks ! I thought you were mentioning the functions I could extend: https://github.com/edgurgel/httpoison#wrapping-httpoisonbase – Flame_Phoenix Jan 15 '19 at 10:08
  • @Flame_Phoenix if you're developing open-source, could you link the code you use this? Much interested in it :) – Tangui Jan 15 '19 at 18:56
  • @Tangui Sorry, the project isn't opensoruce :S – Flame_Phoenix Jan 17 '19 at 11:59