Reputation: 95
What is the correct way of running tests that access multiple databases?
I'm writing a tiny API which has to access multiple databases.
I defined 2 Repos each wrapping a different database:
# config/dev.exs, config/test.exs, ...
config :my_app, MyApp.DbStatusRepo,
adapter: Ecto.Adapters.Postgres,
....
config :my_app, MyApp.DbDefinitionRepo,
adapter: Ecto.Adapters.Postgres,
...
# lib/my_app/db_status_repo.ex
defmodule MyApp.DbStatusRepo do
use Ecto.Repo, otp_app: :my_app
end
# lib/my_app/db_definition_repo.ex
defmodule MyApp.DbDefinitionRepo do
use Ecto.Repo, otp_app: :my_app
end
This works when running the server but I can not find a way to run my tests without them expecting the default MyApp.Repo.
I updated (and added) aliases for both repos.
I changed all references to Repo, but I'm pretty sure it's failing before running my test suite.
Running mix test yields the following error:
(Mix) could not load SourcesApi.Repo, error: :nofile. Please pass a proper repo with the -r option.
Passing another repo with -r option does not change anything. Same error.
My Env:
Thank You for your help.
Upvotes: 5
Views: 2525
Reputation: 10663
First, you need start the repo in lib/my_app.ex
# Start the Ecto repository
worker(MyApp.DbStatusRepo, []),
worker(MyApp.DbDefinitionRepo, []),
Next, prepare repo in test/test_helper.exs
Mix.Task.run "ecto.create", ["--quiet", "-r", "MyApp.DbDefinitionRepo"]
Mix.Task.run "ecto.migrate", ["--quiet", "-r", "MyApp.DbDefinitionRepo"]
Ecto.Adapters.SQL.begin_test_transaction(MyApp.DbDefinitionRepo)
Upvotes: 3
Reputation: 84180
The MyApp.Repo
is aliased in test/support/conn_case.ex
which is why you can call Repo.get(...)
:
using do
quote do
# Import conveniences for testing with connections
use Phoenix.ConnTest
alias MyApp.Repo
...
end
end
setup tags do
unless tags[:async] do
Ecto.Adapters.SQL.restart_test_transaction(MyApp.Repo, [])
end
:ok
end
You will need to update that alias to one of the repos that you have specified. However if you have two repositories that you are using for different purposes then you should explicitly use MyApp.DbStatusRepo.get(...)
and MyApp.DbDefinitionRepo.get(...)
when each one is relevant.
Upvotes: 0