Ошибка передачи сообщения с состоянием [: pid], работает свежесгенерированный pid

#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 сообщение (возможно, бесконечно, используя саморекурсию).