View Source Test Using Mox

To mock HTTP requests in your tests using Mox with the Tesla HTTP client, follow these steps:

1. Define a Mock Adapter

First, define a mock adapter that implements the Tesla.Adapter behaviour. This adapter will intercept HTTP requests during testing.

Create a file at test/support/mocks.ex:

# test/support/mocks.ex
Mox.defmock(MyApp.MockAdapter, for: Tesla.Adapter)

2. Configure the Mock Adapter for Tests

In your config/test.exs file, configure Tesla to use the mock adapter you just defined:

# config/test.exs
config :tesla, adapter: MyApp.MockAdapter

If you are not using the global adapter configuration, ensure that your Tesla client modules are configured to use MyApp.MockAdapter during tests.

3. Set Up Mocking in Your Tests

Create a test module, for example test/demo_test.exs, and set up Mox to define expectations and verify them:

defmodule MyApp.FeatureTest do
  use ExUnit.Case, async: true

  import Mox
  import Tesla.Test

  setup :set_mox_from_context
  setup :verify_on_exit!

  test "example test" do
    #--------- Given - Stubs and Preconditions
    # Expect a single HTTP request to be made and return a JSON response
    expect_tesla_call(
      times: 1,
      returns: json(%Tesla.Env{status: 200}, %{id: 1})
    )

    #--------- When - Run the code under test
    # Make the HTTP request using Tesla
    # Mimic a use case where we create a user
    assert :ok = create_user!(%{username: "johndoe"})

    #--------- Then - Assert postconditions
    # Verify that the HTTP request was made and matches the expected parameters
    assert_received_tesla_call(env, [])
    assert env.status == 200
    assert env.method == :post
    assert env.url == "https://acme.com/users"
    # ...

    # Or you can verify the entire `t:Tesla.Env.t/0` using something like this:
    assert_tesla_env(env, %Tesla.Env{
      method: :post,
      url: "https://acme.com/users",
      body: %{username: "johndoe"},
      status: 200,
    })

    # Verify that the mailbox is empty, indicating no additional requests were
    # made and all messages have been processed
    assert_tesla_empty_mailbox()
  end

  defp create_user!(body) do
    # ...
    Tesla.post!("https://acme.com/users", body)
    # ...
    :ok
  end
end

4. Run Your Tests

When you run your tests with mix test, all HTTP requests made by Tesla will be intercepted by MyApp.MockAdapter, and responses will be provided based on your Mox expectations.