2

我一直在研究这个问题,面临几乎相同的挑战(和答案)

- 除了我的技术非常低,我对自己缺乏洞察力感到非常尴尬 <:/

系统

macOS 10.11.6

$ mix -v
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:8:8] [async-threads:10][hipe] [kernel-poll:false] [dtrace]

Mix 1.3.2

痕迹

$ mix test
...

  1) test /api/v1/blogs#index returns a list of blogs (ScoutServer.BlogControllerTest)
     test/controllers/blog_controller_test.exs:5
     ** (Plug.Conn.AlreadySentError) the response was already sent
     stacktrace:
       (plug) lib/plug/conn.ex:459: Plug.Conn.resp/3
       (plug) lib/plug/conn.ex:446: Plug.Conn.send_resp/3
       (scout_server) web/controllers/blog_controller.ex:1: ScoutServer.BlogController.action/2
       (scout_server) web/controllers/blog_controller.ex:1: ScoutServer.BlogController.phoenix_controller_pipeline/2
       (scout_server) lib/scout_server/endpoint.ex:1: ScoutServer.Endpoint.instrument/4
       (scout_server) lib/phoenix/router.ex:261: ScoutServer.Router.dispatch/2
       (scout_server) web/router.ex:1: ScoutServer.Router.do_call/2
       (scout_server) lib/scout_server/endpoint.ex:1: ScoutServer.Endpoint.phoenix_pipeline/1
       (scout_server) lib/scout_server/endpoint.ex:1: ScoutServer.Endpoint.call/2
       test/controllers/blog_controller_test.exs:17: (test)

.

Finished in 0.1 seconds
5 tests, 1 failure

Randomized with seed 210569

网络/路由器.ex

pipeline :api do
  plug :accepts, ["json"]
end

scope "/api/v1", ScoutServer do
  pipe_through :api
  resources "/blogs", BlogController
end

测试/test_helper.exs

# Add this above `ExUnit.start`
defmodule ScoutServer.Case do
  use ExUnit.CaseTemplate
  alias ScoutServer.Repo

  setup do
    # Explicitly get a connection before each test
    :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo)
  end

  using do
    quote do
      alias ScoutServer.Repo
      use Plug.Test

      # Remember to change this from `defp` to `def` or it can't be used in your
      # tests.
      def send_request(conn) do
        conn
        |> put_private(:plug_skip_csrf_protection, true)
        |> ScoutServer.Endpoint.call([])
      end

    end
  end
end

ExUnit.start

Ecto.Adapters.SQL.Sandbox.mode(ScoutServer.Repo, :manual)

测试/控制器/blog_controller_test.exs

defmodule ScoutServer.BlogControllerTest do
  use ScoutServer.Case, async: false
  alias ScoutServer.Blog

  test "/api/v1/blogs#index returns a list of blogs" do
    blogs =
      %Blog{title: "scout", content: "scouting"}
      |> Repo.insert
      |> List.wrap
    blogs_as_json = Repo.all(Blog)
      |> Poison.encode!(blogs)

    # conn = get conn, "/api/v1/blogs"
    # assert html_response(conn, 200) =~ blogs_as_json

    response = conn(:get, "/api/v1/blogs", blogs_as_json)
      |> send_request

    assert response.status == 200
    assert response.resp_body == blogs_as_json
  end

end
4

1 回答 1

4

我被 blog_controller_test.ex 所吸引,以至于我完全忘记了真实的东西:(

defmodule ScoutServer.BlogController do
  use   ScoutServer.Web, :controller
  alias ScoutServer.Blog

  # plug :action - not sure why, but without the comment the test fails!

  def index(conn, _params) do
    blogs = Repo.all(Blog)
    render conn, blogs: blogs
  end
end

但幸运的是,Pawel Duda 让我摆脱了“消费”——谢谢 Pawel!

实际上 - 插件 :action 的事情已经成为过去,正如这个问题所记录的那样;这再次证明了网络实际上是如何依赖时间/空间的:)

于 2016-09-08T05:42:15.317 回答