В Эликсире как имитировать временные сбои

Я издеваюсь над HTTP-вызовом (используя Tesla) с Mox следующим образом:

  test "Token expiry is handled by re-applying for a token on the fly", %{conn: conn} do
    TeslaMock
    |> expect(:call, 8, fn env, _opts ->
      case env.url do
        "http://fake.server.com/v1/token" ->
          %{env | status: 200, body: Poison.encode!(
                     %{token_type: "Bearer",
                     access_token: "cHBtKbMDNdc3uX2LIhCy9eVwkodhEc87s6e5Fk0lRS",
                     expires_in: 86400})
          }
        "http://fake.server.com/v1/system" ->
          %{env | status: 200, body: Poison.encode!(%{uptime: 10})}
      end
    end)

    assert json_response(get(conn, "/v1/system"), 200) == %{"uptime" => 10}

Мне нужно, чтобы поддельный сервер сначала ответил: срок действия токена 401 истек в /v1/system, мой модуль выдает /v1/token, а затем повторяет попытку /v1/system и завершается успешно. Как это сделать?


person raarts    schedule 27.10.2017    source источник
comment
Какой URL должен сначала возвращать 401?   -  person Dogbert    schedule 27.10.2017
comment
Я отредактировал вопрос. Но я чувствую, куда ты идешь..   -  person raarts    schedule 27.10.2017


Ответы (1)


Вы можете использовать Agent для отслеживания количества запросов, сделанных /v1/system. Затем, если это первый запрос, вернуть 401, иначе 200.

{:ok, counter} = Agent.start_link(fn -> 0 end)

TeslaMock
|> expect(:call, 8, fn env, _opts ->
  case env.url do
    "http://fake.server.com/v1/token" ->
      ...
    "http://fake.server.com/v1/system" ->
      # Increment the counter.
      Agent.update(counter, &(&1 + 1))
      if Agent.get(counter, &(&1)) == 1 do
        # First request.
        %{env | status: 401, body: ...}
      else
        # Second or later request.
        %{env | status: 200, body: Poison.encode!(%{uptime: 10})}
      end
  end
end)
person Dogbert    schedule 27.10.2017