# `Tesla.Test`
[🔗](https://github.com/elixir-tesla/tesla/blob/v1.17.0/lib/tesla/test.ex#L1)

Provides utilities for testing Tesla-based HTTP clients.

# `assert_received_tesla_call`
*macro* 

Asserts that the current process's mailbox contains a `TeslaMox` message.
It uses `assert_received/1` under the hood.

## Parameters

- `expected_env` - The expected `t:Tesla.Env.t/0` passed to the adapter.
- `expected_opts` - The expected `t:Tesla.Adapter.options/0` passed to the
  adapter.
- `opts` - Extra configuration options.
  - `:adapter` - Optional. The adapter to expect the call on. Falls back to
    the `:tesla` application configuration.

## Examples

Asserting that the adapter received a `t:Tesla.Env.t/0` struct with a `200`
status:

    defmodule MyTest do
      use ExUnit.Case, async: true

      require Tesla.Test

      test "returns a 200 status" do
        # given - preconditions
        Tesla.Test.expect_tesla_call(
          times: 2,
          returns: %Tesla.Env{status: 200, body: "OK"}
        )

        # when - run unit of work
        # ... do some work ...
        Tesla.post!("https://acme.com/users")
        # ...

        # then - assertions
        Tesla.Test.assert_received_tesla_call(expected_env, expected_opts)
        Tesla.Test.assert_tesla_env(expected_env, %Tesla.Env{
          url: "https://acme.com/users",
          status: 200,
          body: "OK"
        })
        assert expected_opts == []
        Tesla.Test.assert_tesla_empty_mailbox()
      end
    end

# `assert_tesla_empty_mailbox`
*macro* 

Asserts that the current process's mailbox does not contain any `Tesla.Test`
messages.

This function is designed to be used in conjunction with
`Tesla.Test.assert_received_tesla_call/1` for comprehensive request
testing.

# `assert_tesla_env`

Asserts that two `t:Tesla.Env.t/0` structs match.

## Parameters

- `given_env` - The actual `t:Tesla.Env.t/0` struct received from the request.
- `expected_env` - The expected `t:Tesla.Env.t/0` struct to compare against.
- `opts` - Additional options for fine-tuning the assertion (optional).
  - `:exclude_headers` - A list of header keys to exclude from the assertion.

For the `body`, the function attempts to parse JSON and URL-encoded content
when appropriate.

This function is designed to be used in conjunction with
`Tesla.Test.assert_received_tesla_call/1` for comprehensive request
testing.

## Examples

    defmodule MyTest do
      use ExUnit.Case, async: true

      require Tesla.Test

      test "returns a 200 status" do
        given_env = %Tesla.Env{
          method: :post,
          url: "https://acme.com/users",
        }

        Tesla.Test.assert_tesla_env(given_env, %Tesla.Env{
          method: :post,
          url: "https://acme.com/users",
        })
      end
    end

# `expect_tesla_call`

Expects a call on the given adapter using `Mox.expect/4`. Only available when
`Mox` is loaded.

## Options

- `:times` - Required. The number of times to expect the call.
- `:returns` - Required. The value to return from the adapter.
- `:send_to` - Optional. The process to send the message to. Defaults to
  the current process.
- `:adapter` - Optional. The adapter to expect the call on. Falls back to
  the `:tesla` application configuration.

## Examples

Returning a `t:Tesla.Env.t/0` struct with a `200` status:

    Tesla.Test.expect_tesla_call(
      times: 2,
      returns: %Tesla.Env{status: 200}
    )

Changing the `Mox` mocked adapter:

    Tesla.Test.expect_tesla_call(
      times: 2,
      returns: %Tesla.Env{status: 200},
      adapter: MyApp.MockAdapter
    )

# `html`

```elixir
@spec html(
  %Tesla.Env{
    __client__: term(),
    __module__: term(),
    assigns: term(),
    body: term(),
    headers: term(),
    method: term(),
    opts: term(),
    private: term(),
    query: term(),
    status: term(),
    url: term()
  },
  binary()
) :: %Tesla.Env{
  __client__: term(),
  __module__: term(),
  assigns: term(),
  body: term(),
  headers: term(),
  method: term(),
  opts: term(),
  private: term(),
  query: term(),
  status: term(),
  url: term()
}
```

Puts an HTML response.

    iex> Tesla.Test.html(%Tesla.Env{}, "<html><body>Hello, world!</body></html>")
    %Tesla.Env{
      body: "<html><body>Hello, world!</body></html>",
      headers: [{"content-type", "text/html; charset=utf-8"}],
      ...
    }

# `json`

```elixir
@spec json(
  %Tesla.Env{
    __client__: term(),
    __module__: term(),
    assigns: term(),
    body: term(),
    headers: term(),
    method: term(),
    opts: term(),
    private: term(),
    query: term(),
    status: term(),
    url: term()
  },
  term()
) :: %Tesla.Env{
  __client__: term(),
  __module__: term(),
  assigns: term(),
  body: term(),
  headers: term(),
  method: term(),
  opts: term(),
  private: term(),
  query: term(),
  status: term(),
  url: term()
}
```

Puts a JSON response.

    iex> Tesla.Test.json(%Tesla.Env{}, %{"some" => "data"})
    %Tesla.Env{
      body: ~s({"some":"data"}),
      headers: [{"content-type", "application/json; charset=utf-8"}],
      ...
    }

If the body is binary, it will be returned as is and it will not try to encode
it to JSON.

# `text`

```elixir
@spec text(
  %Tesla.Env{
    __client__: term(),
    __module__: term(),
    assigns: term(),
    body: term(),
    headers: term(),
    method: term(),
    opts: term(),
    private: term(),
    query: term(),
    status: term(),
    url: term()
  },
  binary()
) :: %Tesla.Env{
  __client__: term(),
  __module__: term(),
  assigns: term(),
  body: term(),
  headers: term(),
  method: term(),
  opts: term(),
  private: term(),
  query: term(),
  status: term(),
  url: term()
}
```

Puts a text response.

    iex> Tesla.Test.text(%Tesla.Env{}, "Hello, world!")
    %Tesla.Env{
      body: "Hello, world!",
      headers: [{"content-type", "text/plain; charset=utf-8"}],
      ...
    }

---

*Consult [api-reference.md](api-reference.md) for complete listing*
