配置通道测试超时phoenix

时间:2018-03-17 00:13:03

标签: sockets testing timeout elixir phoenix-framework

我有一个频道,用于在执行某种同步时将消息推送到客户端:

defmodule AppWeb.SyncChannel do
  use AppWeb, :channel

  def join("sync:database", _payload, socket) do
    send(self(), {:sync, :database})

    {:ok, socket}
  end

  def handle_info({:sync, :database}, socket) do
    Process.sleep(2000)
    push(socket, "one", %{})
    Process.sleep(2000)
    push(socket, "two", %{})
    Process.sleep(2000)
    push(socket, "three", %{})

    {:noreply, socket}
  end
end

我对此频道进行了测试:

defmodule AppWeb.SyncChannelTest do
  use AppWeb.ChannelCase, async: false

  alias AppWeb.SyncChannel

  describe "sync:database" do
    setup do
      {:ok, _, socket} = subscribe_and_join(socket(), SyncChannel, "sync:database")

      {:ok, socket: socket}
    end

    test "socket pushes 3 messages", %{socket: _socket} do
      assert_push("one", %{})
      assert_push("two", %{})
      assert_push("three", %{})
    end
  end
end

但是当我运行测试时,我收到错误:

Compiling 1 file (.ex)
...

  1) test sync:database socket pushes 3 messages (AppWeb.SyncChannelTest)
     test/app_web/channels/sync_channel_test.exs:13
     ** (exit) exited in: GenServer.call(#PID<0.478.0>, :socket, 5000)
         ** (EXIT) time out
     stacktrace:
       (elixir) lib/gen_server.ex:830: GenServer.call/3
       (phoenix) lib/phoenix/test/channel_test.ex:360: Phoenix.ChannelTest.join/4
       test/app_web/channels/sync_channel_test.exs:8: AppWeb.SyncChannelTest.__ex_unit_setup_1/1
       test/app_web/channels/sync_channel_test.exs:1: AppWeb.SyncChannelTest.__ex_unit__/2

.

Finished in 5.2 seconds
5 tests, 1 failure

Randomized with seed 119011

如何在测试中配置通道超时,以便handle_info功能运行的时间超过默认值5秒。

我试图在config/文件中配置此功能,但没有快乐,也在app_web/channels/user_socket.ex,但我再也找不到指定timeout

1 个答案:

答案 0 :(得分:1)

Phoenix.ChannelTest.join calls Phoenix.Channel.Server.socket/1 makes a GenServer call to the channel with no configurable timeout从GenServer的状态获取底层套接字。我相信,既然您从join函数向自己发送消息,那么在测试代码能够获取套接字值之前,GenServer会处理该消息,并且由于该调用的默认超时为5秒,因此这个超时错误。

解决方法,使用sendself略微推迟到Process.send_after/3

Process.send_after(self(), {:sync, :database}, 100)

您还需要增加assert_push来电的超时时间,因为超时默认为100毫秒,而您的消息则会在6秒后到达。

assert_push ..., ..., 10000

同样,Process.send_after/3只是一种解决方法。知识渊博的人可能能够提供真正的解决方案。