TestServer - No fuzz mocking of third-party services

Hi everyone!

TestServer is an easy way to mock third-party services in ExUnit.

Features

  • HTTP/1
  • HTTP/2
  • WebSocket
  • TLS with self-signed certificates
  • Flexible FIFO match rules
  • Catches unexpected requests
  • When test finishes verifies there’s no pending routes or websocket handlers to call

Example

test "fetch_url/0" do
  # The test server will autostart the current test server, if not already running
  TestServer.add("/", via: :get)
  TestServer.add("/", via: :get, to: fn conn -> Plug.Conn.send_resp(conn, 200, "second call") end)

  # The URL is derived from the current test server instance
  Application.put_env(:my_app, :url, TestServer.url())

  assert {:ok, "HTTP"} = MyApp.fetch_url()
  assert {:ok, "second call"} = MyApp.fetch_url()
end

Enabling TLS

TestServer.start(scheme: :https)

The key and certificate is generated with x509 on the fly.

WebSocket Example

test "WebSocketClient" do
  {:ok, socket} = TestServer.websocket_init("/ws")
  :ok = TestServer.websocket_handle(socket, to: fn {:text, "ping"}, state -> {:reply, {:text, "pong"}, state})

  {:ok, client} = WebSocketClient.start_link(TestServer.url("/ws"))
  :ok = WebSocketClient.send(client, "ping")
  {:ok, "pong"} = WebSocketClient.receive(client)

  :ok = TestServer.websocket_info(socket, fn state -> {:reply, {:text, "ping"}, state} end)
  {:ok, "ping"} = WebSocketClient.receive(client)
end

I’ve been using this for testing a JSON RPC endpoint and testing the SSL configuration for http adapters in assent.

I hope you find it useful, feel free to contribute! :love_you_gesture:

11 Likes

Hi @danschultzer thanks for releasing this. This looks like a considerable improvement over Bypass. Especially being able to define multiple rules for the same url, which is something you can’t do in Bypass and has always annoyed me. Will try this out as soon as I have to write the next test for an external service.

2 Likes

Especially being able to define multiple rules for the same url, which is something you can’t do in Bypass and has always annoyed me.

True, it was what prompted me to build this library. JSON RPC was impossible to test well with bypass. On top of that I couldn’t use bypass to test handling of bad SSL certificates, and I wished it was a lot more ergonomic for request matching.

2 Likes