在elixir 1.3.2中运行凤凰测试的所有权过程错误

时间:2016-09-09 01:07:04

标签: runtime-error elixir phoenix-framework

我正在通过凤凰教程,但我有这个错误:

 ** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.265.0>.

我没有使用Task.start因此不应该异步运行任何内容,我认为unless标记中的模式足以防止此错误,在test/support/channel_case.ex:< / p>

  setup tags do
    :ok = Ecto.Adapters.SQL.Sandbox.checkout(Watchlist.Repo)

    unless tags[:async] do
      Ecto.Adapters.SQL.Sandbox.mode(Watchlist.Repo, {:shared, self()})
    end

    :ok
  end

所以,我很好奇我是如何解决这个错误的。

这是我运行它的方式:

mix test test/integration/listing_movies_test.exs

我正在使用elixir 1.3.2

更新

defmodule ListingMoviesIntegrationTest do
  use ExUnit.Case, async: true
  use Plug.Test
  alias Watchlist.Router

  @opts Router.init([])
  test 'listing movies' do
    movie = %Movie{name: "Back to the future", rating: 5}
            |> Repo.insert!   <== error happens here

    conn = conn(:get, "/movies")
    response = Router.call(conn, @opts)

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

完整堆栈跟踪:

(db_connection) lib/db_connection.ex:718: DBConnection.checkout/2
       (db_connection) lib/db_connection.ex:619: DBConnection.run/3
       (db_connection) lib/db_connection.ex:463: DBConnection.prepare_execute/4
       (ecto) lib/ecto/adapters/postgres/connection.ex:91: Ecto.Adapters.Postgres.Connection.execute/4
       (ecto) lib/ecto/adapters/sql.ex:235: Ecto.Adapters.SQL.sql_call/6
       (ecto) lib/ecto/adapters/sql.ex:454: Ecto.Adapters.SQL.struct/6
       (ecto) lib/ecto/repo/schema.ex:397: Ecto.Repo.Schema.apply/4
       (ecto) lib/ecto/repo/schema.ex:193: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4
       (ecto) lib/ecto/repo/schema.ex:124: Ecto.Repo.Schema.insert!/4
       test/integration/listing_movies_test.exs:13: (test)

并在test_helper中实际调用,因为我输入了一个调试语句:

ExUnit.start

Ecto.Adapters.SQL.Sandbox.mode(Watchlist.Repo, :manual)
Ecto.Adapters.SQL.Sandbox.mode(Watchlist.Repo, {:shared, self()})

3 个答案:

答案 0 :(得分:5)

use ExUnit.Case, async: true
use Plug.Test

你在“test / support / channel_case.ex”中有安装钩子的代码,但你没有在测试中的任何地方使用它,或者至少你不清楚它是否使用它。如果您可以添加以下内容将会很有帮助:

IO.puts "#{inspect __MODULE__}: setup is getting called."

你的setup hook的代码中的某个地方。这将确保代码实际运行。我怀疑你在我之前的回答中所做的评论这段代码已经死了。

defmodule ListingMoviesIntegrationTest do
  use ExUnit.Case, async: true
  use Plug.Test
  alias Watchlist.Router

  setup do
    :ok = Ecto.Adapters.SQL.Sandbox.checkout(Watchlist.Repo)
    Ecto.Adapters.SQL.Sandbox.mode(Watchlist.Repo, {:shared, self()})
    :ok
  end


  @opts Router.init([])
  test 'listing movies' do
    movie = %Movie{name: "Back to the future", rating: 5}
        |> Repo.insert!   <== error happens here

    conn = conn(:get, "/movies")
    response = Router.call(conn, @opts)

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

答案 1 :(得分:0)

我猜你正在跳过这一行

Ecto.Adapters.SQL.Sandbox.mode(Watchlist.Repo, {:shared, self()})

,因为

iex(1)> unless true do
...(1)>   IO.puts "test"
...(1)> end
nil
iex(2)> unless false do
...(2)>   IO.puts "test"
...(2)> end
test
:ok

你有没有尝试过:

if tags[:async] do
  Ecto.Adapters.SQL.Sandbox.mode(Watchlist.Repo, {:shared, self()})
end

答案 2 :(得分:0)

我遇到了同样的错误,在以Elixir 1.8.2,Phoenix 1.4.1为例的情况下:在查看this Elixir forum thread之后,我将test_helpers.exs更改为下面的行以包含适配器池模式从手动到自动。

Ecto.Adapters.SQL.Sandbox.mode(MyApp.Repo, :auto)

您可以在Hex Ecto docs

上详细了解有关模式,池检出和所有权的信息。