Im doing integration tests in my test database if my logic saves the correct records. Although im running pool: Ecto.Adapters.SQL.Sandbox the records are not flushed after each mix test
Hello, You don’t give a lot of details, so it’s hard to give You an answer…
What do You have in the file test/test_helper.exs?
Is that some legacy project?
Hey there
No its not a legacy project.
test "if compatibility fails, make a record with status: :not_available" do
VinWorker.request_data_clearance("WBY2Z2205EX7GB012", "O00O010O184TA")
details = Bmw.get_clearance_by_cid("11111111-1111-1111-1111-111111111111")
assert "not_available" == details.status
end
test "if compatibility succeeds, make a record with :pending" do
VinWorker.request_data_clearance("WBAVB71470VOTP000", "S00I000M001OK")
details = Bmw.get_clearance_by_cid("11111111-1111-1111-1111-111111111112")
assert "pending" == details.status
end
These two records persist in the test database.
My test helper file is just ExUnit.start(exclude: [:pending])
This is mine…
ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(Caissa.Repo, :manual)
BTW if I create a new project…
$ mix phx.new koko
$ cat koko/test/test_helper.exs
ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(Koko.Repo, :manual)
hey,
If i add the line Ecto.Adapters.SQL.Sandbox.mode(DB.Repo, :manual)
I get this error:
6) Logic.VinWorkerTest: failure on setup_all callback, all tests have been invalidated
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.597.0>.
When using ownership, you must manage connections in one
of the four ways:
* By explicitly checking out a connection
* By explicitly allowing a spawned process
* By running the pool in shared mode
* By using :caller option with allowed process
The first two options require every new process to explicitly
check a connection out or be allowed by calling checkout or
allow respectively.
The third option requires a {:shared, pid} mode to be set.
If using shared mode in tests, make sure your tests are not
async.
The fourth option requires [caller: pid] to be used when
checking out a connection from the pool. The caller process
should already be allowed on a connection.
If you are reading this error, it means you have not done one
of the steps above or that the owner process has crashed.
See Ecto.Adapters.SQL.Sandbox docs for more information.
Also important is this file
test/support/data_case.ex
It would be helpful to know
- What Phoenix version?
- Did You edit test config yourself?
- What happens on a new project?
Hey, i found the solution, I had to Explicitly get a connection before each test , so i did setup do
# Explicitly get a connection before each test
:ok = Ecto.Adapters.SQL.Sandbox.checkout(DB.Repo) end
Thank you for your help!
This is normally set in data_case.ex
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(YourDB.Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(YourDB.Repo, {:shared, self()})
end
:ok
end
But it’s nice You find a solution
ok, can you show me your data_case.ex file
This is a standard data_case file (I did not edit after project creation)
defmodule Rbax.DataCase do
@moduledoc """
This module defines the setup for tests requiring
access to the application's data layer.
You may define functions here to be used as helpers in
your tests.
Finally, if the test case interacts with the database,
it cannot be async. For this reason, every test runs
inside a transaction which is reset at the beginning
of the test unless the test case is marked as async.
"""
use ExUnit.CaseTemplate
using do
quote do
alias Rbax.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query
import Rbax.DataCase
end
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Rbax.Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Rbax.Repo, {:shared, self()})
end
:ok
end
@doc """
A helper that transforms changeset errors into a map of messages.
assert {:error, changeset} = Accounts.create_user(%{password: "short"})
assert "password is too short" in errors_on(changeset).password
assert %{password: ["password is too short"]} = errors_on(changeset)
"""
def errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
Regex.replace(~r"%{(\w+)}", message, fn _, key ->
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
end)
end)
end
end
What is your approach for umbrella project? Because if I do like this for one or two projects, the first one works but the another projects have many errors. Especially when your Ecto is in a project under umbrella.