Skip to content

Pascal736/websocket_mock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WebSocketMock

Hex.pm Documentation

Lightweight WebSocket mock server and mock client for testing.

Installation

Add websocket_mock to your test dependencies in mix.exs:

def deps do
  [
    {:websocket_mock, "~> 0.3.0", only: :test}
  ]
end

Quick Start

iex> alias WebSocketMock.MockServer
iex> alias WebSocketMock.MockClient
iex>
iex> {:ok, server} = MockServer.start()
iex> {:ok, client} = MockClient.start(server.url)
iex> MockServer.is_connected?(server)
true
iex> MockServer.num_connections(server)
1
iex> [%{client_id: client_id}] = MockServer.list_clients(server)
iex> MockServer.send_message(server, client_id, {:text, "Hello!"})
:ok
iex> MockClient.send_message(client, {:text, "world"})
:ok
iex>
iex> MockServer.received_messages(server)
[{:text, "world"}]
iex> MockClient.received_messages(client)
[{:text, "Hello!"}]

iex> alias WebSocketMock.MockServer
iex> alias WebSocketMock.MockClient
iex>
iex> {:ok, server} = MockServer.start()
iex> {:ok, client} = MockClient.start(server.url)
iex> # Set up automatic replies
iex>  MockServer.reply_with(server, {:text, "ping"}, {:text, "pong"})
iex>  # Also works with functions as filters
iex>  MockServer.reply_with(server, fn {opcode, msg} -> msg == "ping" end, {:text, "pong"})
iex>   
iex> MockClient.send_message(client, {:text, "ping"})
iex> Process.sleep(20)
iex> MockClient.received_messages(client)
[{:text, "pong"}]
iex> # Mockserver accepts callbacks which run before sending the reply
iex> MockServer.reply_with(server, "ping", fn {opcode, msg} -> {opcode, msg <> " pong"} end)
iex> MockClient.send_message(client, {:text, "ping"})
iex> Process.sleep(20)
iex> MockClient.received_messages(client)
[{:text, "pong"}, {:text, "ping pong"}]

Usage in Tests

defmodule MyAppTest do
  use ExUnit.Case
  alias WebSocketMock.MockServer
  alias WebSocketMock.MockClient

  setup do
    {:ok, server} = MockServer.start()
    on_exit(fn -> MockServer.stop(server) end)
    %{server: server}
  end

  test "websocket client connects and receives messages", %{server: server} do
    {:ok, client} = MockClient.start(server.url)
    
    [%{client_id: client_id}] = MockServer.list_clients(server)
    MockServer.send_message(server, client_id, {:text, "test message"})

    assert MockClient.received_messages(client) == [{:text, "test message"}]
  end


  test "client sends message to server", %{server: server} do
    {:ok, client} = MockClient.start(server.url)
    
    MockClient.send_message(client, {:text, "Hello Server!"})
    
    assert MockServer.received_messsages(server) == [{:text, "Hello Server!"}]
  end


  test "client handles response", %{server: server} do 
    {:ok, client} = MockClient.start(server.url)
    MockServer.reply_with(server, {:text, "hello"}, {:text, "world"})
    MockServer.reply_with(server, {:text, "buy"}, {:text, "see ya"})

    MockClient.send_message(client, {:text, "hello"})
    assert MockClient.received_messages(client) == [{:text, "world"}]

    MockClient.send_message(client, {:text, "buy"})
    assert {:text, "see ya"} in MockClient.received_messages(client)
  end
end

Documentation

Full documentation is available at https://hexdocs.pm/websocket_mock.

Known Issues

  • Tests are flaky because of the asynchronous nature of the requests. Needs improvement.
  • The mock server currently crashes on start when the randomly selected port is already in use.

License

MIT License. See LICENSE for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages