#elixir #ex-unit
#elixir #ex-unit
Вопрос:
Мой второй тест завершается неудачей.
1) test it jumps when it can (RunnerTest)
test/runner_test.exs:15
No message matching %{y: 1} after 100ms.
The process mailbox is empty.
stacktrace:
test/runner_test.exs:18: (test)
defmodule RunnerTest do
use ExUnit.Case
doctest Runner
setup_all do
{:ok, pid: spawn(fn -> Runner.input() end)}
end
test "it increases its x position", state do
avatar = %{x: 0, y: 0}
send state[:pid], {:run, self, avatar}
assert_receive %{x: 1}
end
test "it jumps when it can", state do
avatar = %{x: 0, y: 0}
send state[:pid], {:jump, self, avatar}
assert_receive %{y: 1}
end
end
Модуль Runner:
defmodule Runner do
def input do
receive do
{:run, sender, mover} -> send sender, run(mover)
{:jump, sender, mover} -> send sender, jump(mover)
end
end
defp run(mover) do
Map.merge(mover, %{x: mover.x 1})
end
defp jump(mover) do
case {mover.y} do
{0} ->
Map.merge(mover, %{y: mover.y 1})
_ ->
mover
end
end
end
Этот тест пройден:
test "it jumps when it can", state do
avatar = %{x: 0, y: 0}
pid = spawn(fn -> Runner.input() end)
send pid, {:jump, self, avatar}
assert_receive %{y: 1}
end
Почему 1 тест (запуск) работает с настройкой, но не другой (переход)?
Комментарии:
1. Вы не вызываете
input
снова послеreceive
, поэтому ваш процесс, вероятно, умирает после ответа на 1 сообщение.2. Спасибо, Догберт! Я ошибочно принял setup_all за запуск каждый раз
Ответ №1:
Почему 1 тест (запуск) работает с настройкой, но не другой (переход)?
Это потому, что ваш процесс отвечает только на одно сообщение, а затем умирает, и вы используете setup_all
вместо setup
, что означает, что процесс запускается только один раз, перед запуском первого теста, и то же pid
самое передается всем тестам.
Вы можете либо изменить setup_all
setup
, если хотите создавать новый процесс для каждого теста, либо заставить ваш процесс отвечать более чем на 1 сообщение (возможно, бесконечно, используя саморекурсию).