我正在学习phoenix教程,但我遇到了以下错误:
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.265.0>.
我没有使用Task.start
,所以任何东西都不应该异步运行,我认为在unless
标签中使用模式就足以防止test/support/channel_case.ex
:中出现此错误
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
我正在使用长生不老药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()})
use ExUnit.Case, async: true
use Plug.Test
你在"test/support/channel_case.ex"中有安装挂钩的代码,但你在测试中没有在任何地方使用它,或者至少不清楚你是否使用了它。如果你能添加以下内容,那将很有帮助:
IO.puts "#{inspect __MODULE__}: setup is getting called."
安装挂钩代码中的某个位置。这将确保代码实际运行。从你在我之前的回答中对这个代码的评论来看,我的怀疑已经消失了。
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
...
我在Elixir 1.8.2,Phoenix 1.4.1上遇到了同样的错误:在查看了这个Elixir论坛线程后,我将test_helpers.exs
更改为具有以下行,以将适配器池模式从手动更改为自动。
Ecto.Adapters.SQL.Sandbox.mode(MyApp.Repo, :auto)
您可以在Hex-Ecto文档上阅读更多关于模式、池签出和所有权的信息
我猜您正在跳过这一行
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