View Source Sham (sham v1.0.1)

Sham is a mock HTTP(S) server useful for testing HTTP(S) clients.

Summary

Functions

Expect at least one call to the Sham instance using any method and at any path.

Expect at least one call to the Sham instance using the given method and path.

Expect at most one call to the Sham instance using any method and at any path.

Expect at most one call to the Sham instance using the given method and path.

Forces the Sham instance to pass regardless of whether a valid request was sent to the sham port or not.

Starts a new Sham instance.

Provide a callback to handle any requests to the Sham instance without assertions.

Provide a callback to handle any requests to the Sham instance using the given method and path without assertions.

Types

@type sham_opts() :: [ssl: boolean(), keyfile: String.t(), certfile: String.t()]
@opaque t()

Functions

@spec expect(t(), (Plug.Conn.t() -> Plug.Conn.t())) :: t()

Expect at least one call to the Sham instance using any method and at any path.

Examples

iex> sham = Sham.start()
iex> Sham.expect(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}
iex> ShamTest.post("http://localhost:#{sham.port}/other", "foo=bar")
{:ok, 200, "Hello"}

sham = Sham.start()
Sham.expect(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
** (ExUnit.AssertionError) No HTTP request was received by Sham

If no request is sent to the sham port, an assertion error will be raised.

Link to this function

expect(sham, method, path, callback)

View Source
@spec expect(
  t(),
  method :: String.t(),
  path :: String.t(),
  (Plug.Conn.t() -> Plug.Conn.t())
) :: t()

Expect at least one call to the Sham instance using the given method and path.

  • method - The HTTP method to expect. Should be one of "GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", or "OPTIONS" or (Anything Plug supports).
  • path - The path to expect

Examples

iex> sham = Sham.start()
iex> Sham.expect(sham, "GET", "/hello", fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}

# Sending a request that does not match an expectation will result in an assertion error
ShamTest.post("http://localhost:#{sham.port}/other", "foo=bar")
{:ok, 500, "Unexpected request to Sham: POST /other"}
** (ExUnit.AssertionError) Unexpected request to Sham: POST /other

If no request is sent to the sham port using the given method and path, an assertion error will be raised.

Link to this function

expect_once(sham, callback)

View Source
@spec expect_once(t(), (Plug.Conn.t() -> Plug.Conn.t())) :: t()

Expect at most one call to the Sham instance using any method and at any path.

You can stack multiple calls to expect_once/4 to expect multiple requests.

Examples

iex> sham = Sham.start()
iex> Sham.expect_once(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}

iex> sham = Sham.start()
iex> Sham.expect_once(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}
iex> Sham.expect_once(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "World") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "World"}

# Sending a more than one request will result in an assertion error
ShamTest.post("http://localhost:#{sham.port}/other", "foo=bar")
{:ok, 500, "Exceeded expected requests to Sham: POST /other"}
** (ExUnit.AssertionError) Exceeded expected requests to Sham: POST /other

If a request is sent to the sham port using a different method or path, an assertion error will be raised.

Link to this function

expect_once(sham, method, path, callback)

View Source
@spec expect_once(
  t(),
  method :: String.t(),
  path :: String.t(),
  (Plug.Conn.t() -> Plug.Conn.t())
) :: t()

Expect at most one call to the Sham instance using the given method and path.

You can stack multiple calls to expect_once/4 to expect multiple requests.

  • method - The HTTP method to expect. Should be one of "GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", or "OPTIONS" or (Anything Plug supports).
  • path - The path to expect

Examples

iex> sham = Sham.start()
iex> Sham.expect_once(sham, "GET", "/hello", fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}

iex> sham = Sham.start()
iex> Sham.expect_once(sham, "GET", "/hello", fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}
iex> Sham.expect_once(sham, "GET", "/hello", fn conn -> Plug.Conn.send_resp(conn, 200, "World") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "World"}

# Sending a more than one request with the same method and path will result in an assertion error
ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 500, "Exceeded expected requests to Sham: GET /hello"}
** (ExUnit.AssertionError) Exceeded expected requests to Sham: GET /hello

If no request is sent to the sham port using the given method and path, an assertion error will be raised.

@spec pass(t()) :: t()

Forces the Sham instance to pass regardless of whether a valid request was sent to the sham port or not.

Examples

iex> sham = Sham.start()
iex> Sham.expect(sham, "GET", "/hello", fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.post("http://localhost:#{sham.port}/other", "foo=bar")
{:ok, 500, "Unexpected request to Sham: POST /other"}
iex> Sham.pass(sham)

iex> sham = Sham.start()
iex> Sham.expect(sham, "GET", "/hello", fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> Sham.pass(sham)

No assertions will be raised.

@spec start(sham_opts()) :: t() | {:error, term()}

Starts a new Sham instance.

Options

  • :ssl - Whether to start the server in SSL mode. Defaults to false.
  • :keyfile - The path to an SSL keyfile. Defaults to an internal self-signed key.
  • :certfile - The path to an SSL certfile. Defaults to an internal self-signed certificate.

Examples

sham = Sham.start()
Sham.expect(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)

sham = Sham.start(ssl: true)
Sham.expect(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
@spec stub(t(), (Plug.Conn.t() -> Plug.Conn.t())) :: t()

Provide a callback to handle any requests to the Sham instance without assertions.

No exceptions will be raised if no requests are sent to the sham port.

Examples

iex> sham = Sham.start()
iex> Sham.stub(sham, fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}
iex> ShamTest.post("http://localhost:#{sham.port}/other", "foo=bar")
{:ok, 200, "Hello"}
Link to this function

stub(sham, method, path, callback)

View Source
@spec stub(
  t(),
  method :: String.t(),
  path :: String.t(),
  (Plug.Conn.t() -> Plug.Conn.t())
) :: t()

Provide a callback to handle any requests to the Sham instance using the given method and path without assertions.

No exceptions will be raised if no requests are sent to the sham port using the given method and path.

Examples

iex> sham = Sham.start()
iex> Sham.stub(sham, "GET", "/hello", fn conn -> Plug.Conn.send_resp(conn, 200, "Hello") end)
iex> ShamTest.get("http://localhost:#{sham.port}/hello")
{:ok, 200, "Hello"}

# Sending a request with a different method and path will result in an assertion error
ShamTest.post("http://localhost:#{sham.port}/other", "foo=bar")
{:ok, 500, "Unexpected request to Sham: POST /other"}
** (ExUnit.AssertionError) Unexpected request to Sham: POST /other