I have a module for Happymeal
which takes consists of :food
(String) and :toy
(simple database object with :id
as primary key)
The constructor looks like this:
defmodule Myapp.Happymeal do
alias Myapp.{Repo, Toy}
defstruct [
:toy,
:food
]
@type t :: %__MODULE__{
toy: Toy,
food: String
}
def new(%{toy_id: toy_id, food: food}) do
toy = Repo.get(Toy, toy_id)
{:ok,
%__MODULE__{
toy: toy,
food: food
}}
end
end
When I run Myapp.Happymeal.new(%{toy_id: 1, food: "burger"})
in iex
I get back a Happymeal
as expected.
However, when I run this from a test:
defmodule MyappTest do
use ExUnit.Case
describe "Happymeal tests" do
test "Happymeal can be created" do
{:ok, happymeal} = Myapp.Happymeal.new(%{toy_id: 1, food: "burger"})
IO.inspect(happymeal)
end
end
end
… I get an error:
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.341.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.
code: {:ok, happymeal} = Myapp.Happymeal.new(%{toy_id: 1, food: "burger"})
How can I make this style of constructor work from within a phoenix test?