fake_server v2.1.0 FakeServer.ResponseFactory
Create reusable and customizable answers for your servers.
With response factories it is possible to create a default format of a given response and identify it with a name so that it can be shared across several test cases.
They are inspired by the ExMachina's factories, and were created to suit the use case where it is necessary to modify both the body or headers of a given response while testing different scenarios.
What is a factory?
A factory is just a function with no arguments inside a module that use FakeServer.ResponseFactory
.
The function name must end in _response
and it must return a FakeServer.Response
structure. The factory name is everything before _response
.
# test/support/my_response_factory.ex
defmodule MyResponseFactory do
use FakeServer.ResponseFactory
def person_response do
ok(%{
name: Faker.Name.name,
email: Faker.Internet.free_email,
company: %{name: Faker.Company.name, county: Faker.Address.country}
}, %{"Content-Type" => "application/json"})
end
end
Using a factory
To use a factory, just call ResponseFactory.build(:factory_name)
. This macro accepts two optinal arguments:
body_opts
: This is a list with keys whose values should be overwritten in the body of factory's response. If any of the keys is set tonil
, it will be deleted from the original body. If a key that does not exist on the original body is set here, it will be ignored.header_opts
: This is a map with the headers whose values should be overwritten. If any of the headers is set tonil
, it will be deleted from the original header list. If a key that does not exist on the original header list is set here, it will be included on the headers list.
You can also create a list of responses with MyResponseFactory.build_list(list_size, :factory_name)
.
Example
# test/my_app/some_test.exs
defmodule MyApp.SomeTest do
use ExUnit.Case, async: false
import FakeServer
test_with_server "basic factory usage" do
customized_response = %{body: body} = MyResponseFactory.build(:person)
person = Poison.decode!(body)
route "/person", customized_response
response = HTTPoison.get! FakeServer.address <> "/person"
body = Poison.decode!(response.body)
assert response.status_code == 200
assert person["name"] == body["name"]
assert person["email"] == body["email"]
assert person["company"]["name"] == body["company"]["name"]
assert person["company"]["country"] == body["company"]["country"]
end
test_with_server "setting custom attributes" do
route "/person", do: MyResponseFactory.build(:person, name: "John", email: "john@myawesomemail.com")
person = Poison.decode!(body)
response = HTTPoison.get! FakeServer.address <> "/person"
body = Poison.decode!(response.body)
assert response.status_code == 200
assert body["name"] == "John"
assert body["email"] == "john@myawesomemail.com"
end
test_with_server "deleting an attribute" do
route "/person", do: MyResponseFactory.build(:person, name: nil)
response = HTTPoison.get! FakeServer.address <> "/person"
body = Poison.decode!(response.body)
assert response.status_code == 200
assert body["name"] == nil
end
test_with_server "overriding a header" do
route "/person", do: MyResponseFactory.build(:person, %{"Content-Type" => "application/x-www-form-urlencoded"})
response = HTTPoison.get! FakeServer.address <> "/person"
assert response.status_code == 200
assert Enum.any?(response.headers, fn(header) -> header == {"Content-Type", "application/x-www-form-urlencoded"} end)
end
test_with_server "deleting a header" do
route "/person", do: MyResponseFactory.build(:person, %{"Content-Type" => nil})
response = HTTPoison.get! FakeServer.address <> "/person"
assert response.status_code == 200
refute Enum.any?(response.headers, fn(header) -> header == {"Content-Type", _} end)
end
test_with_server "create a list of responses" do
person_list = MyResponseFactory.build_list(3, :person)
route "/person", do: person_list
Enum.each(person_list, fn(person) ->
response = HTTPoison.get! FakeServer.address <> "/person"
body = Poison.decode!(response.body)
assert response.status_code == 200
assert person.body[:name] == body["name"]
assert person.body[:email] == body["email"]
assert person.body[:company][:name] == body["company"]["name"]
assert person.body[:company][:country] == body["company"]["country"]
end)
end
end