My preferred way to write parameterized tests in Elixir.
# The helper functions for the test module. To make it possible to import | |
# this helper module in the test module, define this module outside the context that uses it. | |
defmodule MyTest.Helpers do | |
@spec fake_params(Enumrable.t()) :: map | |
def fake_params(override \\ %{}) do | |
%{ | |
country: "jp", | |
phone_number: Faker.phone_number(), | |
locale: "ja", | |
company: "My Company", | |
department: "My Department", | |
email: Faker.Internet.email(), | |
first_name: Faker.Name.first_name(), | |
last_name: Faker.Name.last_name() | |
} | |
|> Map.merge(Map.new(override)) | |
end | |
end | |
defmodule MyTest do | |
use MyApp.ConnCase | |
# Because I'd like to use functions in the helper module both in parameterized cases and | |
# test cases, alias and import it. | |
alias MyTest.Helpers | |
import Helpers | |
describe "signup" do | |
for {description, signup_params} <- [ | |
# You cannot invoke functions in the testing module which is not defined yet. | |
# So we need the helper module. | |
"all filled": Helpers.fake_params(), | |
"department can be omitted": Helpers.fake_params(department: nil), | |
"department can be null": Helpers.fake_params() |> Map.delete("department") | |
] do | |
# You cannot use variables in this context in the context inside a test case. | |
# So you have to use module attributes or `@tag` feature in ExUnit. Personally, | |
# I prefer the latter. | |
@tag signup_params: signup_params | |
test "no errors: #{description}", %{conn: conn, signup_params: signup_params} do | |
# ... | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment