Search code examples
elixirphoenix-frameworkecto

How to test a multi database Elixir (Phoenix, Ecto) app


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:

  • Elixir: 1.1.1
  • Phoenix: 1.0.3
  • Ecto: 1.0.6

Thank You for your help.


Solution

  • 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)