如何在ecto事务中测试正文流的响应?

时间:2018-01-30 17:15:18

标签: unit-testing elixir phoenix-framework ecto

我正在尝试为一个端点编写单元测试,该端点以块的形式传输其响应。通过浏览器访问时,我可以验证内容是否完全正确流式传输。但是当我通过我的测试套件访问端点时,响应体是空的。

控制器动作示例

def stream_csv(conn, _params) do
  conn = conn
  |> put_resp_content_type("text/csv")
  |> put_resp_header("content-disposition", "data.csv")
  |> send_chunked(200)

  Repo.transaction(fn ->
    {:ok, conn} = chunk(conn, "csv data part")
  end)

  conn
end

单元测试示例

test "stream endpoint" do
  body = build_conn()
  |> Phoenix.ConnTest.get("/stream_endpoint")
  |> Phoenix.ConnTest.response(200)

  assert body =~ "csv data part"
end

这会导致断言失败,其中body是空二进制""

我觉得应该有一种方法可以在断言之前等待所有块,或者我可能忽略了一些显而易见的事情。

修改

我最初编写的示例按预期工作。似乎使事情复杂化的是从提供给chunk的回调中调用Repo.transaction。我已经更新了问题和示例,以便更好地反映问题。

1 个答案:

答案 0 :(得分:0)

我遇到了这个问题,并尝试了几种方法上班并最终做到了这一点 solution using mocks

所以这是当我们调用Plug.Conn.chunk(conn,chunk)时,插件会调用<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradient_with_bottom_curve" android:alpha="0.4"/> 。从那里,应该将块发送到服务器(例如牛仔)以进行进一步处理。 conn不再知道该块了。

为解决这个问题,我将分块功能移至另一个功能,副作用最小且易于模拟

conn.adapter.chunk

在响应处理程序中

defmodule MyApp.ControllerUtils do
    use MyaAppWeb, :controller

    @callback chunk_to_conn(map(), String.t()) :: map()
    def chunk_to_conn(conn, current_chunk) do
       conn |> chunk(current_chunk)
    end
end

现在,在您的测试中,您将模拟分块功能以给您块,并使用类似def stream_csv(conn, _params) do conn = conn |> put_resp_content_type("text/csv") |> put_resp_header("content-disposition", "data.csv") |> send_chunked(200) Repo.transaction(fn -> {:ok, conn} = MyApp.ControllerUtils.chunk_to_conn(conn, "csv data part") end) conn end 的东西来存储和加入这些块,或在它们出现时对其进行断言。

Agent