0

我正在 Docker 容器中使用 Phoenix 框架开发 Web 应用程序。以下是 dockerfile 中有关如何安装 phoenix 的相关行:

RUN git clone https://github.com/phoenixframework/phoenix
RUN cd /home/user/phoenix/installer/ && MIX_ENV=prod mix do archive.build, archive.install --force

这一切都很好。我可以使用以下命令生成一个新的 phoenix 项目:

mix phx.new hello_phoenix

但是,当我生成一个新频道时:

混合 phx.gen.channel hello_channel

并将这一行添加到用户套接字文件

channel "hello_channel:lobby", HelloPhoenixWeb.HelloChannelChannel

然后运行

mix test

我收到以下错误:

warning: Phoenix.ChannelTest.socket/2 is deprecated, please call socket/3 instead
  (phoenix) lib/phoenix/test/channel_test.ex:234: Phoenix.ChannelTest."MACRO-socket"/3
  (elixir) src/elixir_dispatch.erl:186: :elixir_dispatch.expand_macro_fun/6
  (elixir) src/elixir_dispatch.erl:149: :elixir_dispatch.do_expand_import/6
  (elixir) src/elixir_dispatch.erl:81: :elixir_dispatch.dispatch_import/5
  (elixir) src/elixir_expand.erl:539: :elixir_expand.expand_arg/2
  (stdlib) lists.erl:1354: :lists.mapfoldl/3
  (elixir) src/elixir_expand.erl:548: :elixir_expand.expand_args/2
  (elixir) src/elixir_expand.erl:646: :elixir_expand.expand_remote/7
  (elixir) src/elixir_dispatch.erl:207: :elixir_dispatch.expand_quoted/6
  (elixir) src/elixir_expand.erl:10: :elixir_expand.expand/2
  (elixir) src/elixir_expand.erl:489: :elixir_expand.expand_block/4
  (elixir) src/elixir_expand.erl:39: :elixir_expand.expand/2
  (elixir) src/elixir_clauses.erl:19: :elixir_clauses.def/2
  (elixir) src/elixir_def.erl:146: :elixir_def."-store_definition/10-lc$^0/1-0-"/2
  (elixir) src/elixir_def.erl:146: :elixir_def.store_definition/10
  test/hello_phoenix_web/channels/hello_channel_channel_test.exs:6: (module)
  (elixir) src/elixir_compiler.erl:85: :elixir_compiler.dispatch/6

..
== Compilation error in file test/hello_phoenix_web/channels/hello_channel_channel_test.exs ==
** (CaseClauseError) no case clause matching: [{"/socket", HelloPhoenixWeb.UserSocket, [], [{["socket", "websocket"], {:websocket, HelloPhoenixWeb.UserSocket, [serializer: [{Phoenix.Socket.V1.JSONSerializer, "~> 1.0.0"}, {Phoenix.Socket.V2.JSONSerializer, "~> 2.0.0"}], timeout: 60000, transport_log: false, compress: false]}}]}]
    (phoenix) lib/phoenix/test/channel_test.ex:240: Phoenix.ChannelTest.first_socket!/1
    (phoenix) lib/phoenix/test/channel_test.ex:213: Phoenix.ChannelTest.build_socket/4
    (phoenix) expanding macro: Phoenix.ChannelTest.socket/2
    test/hello_phoenix_web/channels/hello_channel_channel_test.exs:8: HelloPhoenixWeb.HelloChannelChannelTest.__ex_unit_setup_1/1
    (elixir) expanding macro: Kernel.|>/2
    test/hello_phoenix_web/channels/hello_channel_channel_test.exs:9: HelloPhoenixWeb.HelloChannelChannelTest.__ex_unit_setup_1/1
    (elixir) lib/code.ex:677: Code.require_file/2
    (elixir) lib/kernel/parallel_compiler.ex:201: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6

这是mix phx.gen.channel任务生成的通道文件的代码:

defmodule HelloPhoenixWeb.HelloChannelChannel do
  use HelloPhoenixWeb, :channel

  def join("hello_channel:lobby", payload, socket) do
    if authorized?(payload) do
      {:ok, socket}
    else
      {:error, %{reason: "unauthorized"}}
    end
  end

  # Channels can be used in a request/response fashion
  # by sending replies to requests from the client
  def handle_in("ping", payload, socket) do
    {:reply, {:ok, payload}, socket}
  end

  # It is also common to receive messages from the client and
  # broadcast to everyone in the current topic (hello_channel:lobby).
  def handle_in("shout", payload, socket) do
    broadcast socket, "shout", payload
    {:noreply, socket}
  end

  # Add authorization logic here as required.
  defp authorized?(_payload) do
    true
  end
end

这是生成的测试代码:

defmodule HelloPhoenixWeb.HelloChannelChannelTest do
  use HelloPhoenixWeb.ChannelCase

  alias HelloPhoenixWeb.HelloChannelChannel

  setup do
    {:ok, _, socket} =
      socket("user_id", %{some: :assign})
      |> subscribe_and_join(HelloChannelChannel, "hello_channel:lobby")

    {:ok, socket: socket}
  end

  test "ping replies with status ok", %{socket: socket} do
    ref = push socket, "ping", %{"hello" => "there"}
    assert_reply ref, :ok, %{"hello" => "there"}
  end

  test "shout broadcasts to hello_channel:lobby", %{socket: socket} do
    push socket, "shout", %{"hello" => "all"}
    assert_broadcast "shout", %{"hello" => "all"}
  end

  test "broadcasts are pushed to the client", %{socket: socket} do
    broadcast_from! socket, "broadcast", %{"some" => "data"}
    assert_push "broadcast", %{"some" => "data"}
  end
end

我正在处理的一个实际项目以及我为隔离问题而启动的一个测试项目遇到了这个问题。

是什么导致生成器进行的测试出现编译错误?

4

1 回答 1

0

Phoenix 框架 1.4 仍处于开发状态,因此出现错误也就不足为奇了。Phoenix 框架 1.3.x 是当前的稳定版本,您应该使用它。如果你知道你在用 1.4-dev 构建做什么,那么你应该在 Phoenix Framework github repo 上提出一个问题。

于 2018-08-10T04:55:54.347 回答