Hello all! I’m in the process of writing an application with a couple moving parts, but unit testing it is making me question everything.
My application supervises three processes:
children = [
{DynamicSupervisor, strategy: :one_for_one, name: MyApp.SuperSpider},
{MyApp.Database, name: MyApp.CurrentDatabase},
{MyApp.SiteAPI, name: MyApp.SiteAPI},
]
When the SiteAPI starts, it loads and starts processes based on what is in the database:
def init(opts) do
super_spider = opts |> Keyword.get(:super_spider, MyApp.SuperSpider)
db = opts |> Keyword.get(:db, MyApp.CurrentDatabase)
sites = db |> Database.get_sites()
spiders = sites |> Enum.reduce(%{}, fn (site, acc) ->
{:ok, new_pid} = DynamicSupervisor.start_child(
super_spider, {MyApp.Spider, {site, db}}
)
Map.put(acc, site.id, new_pid)
end)
{:ok, %{db: db, super_spider: super_spider, spiders: spiders}}
end
Everything as near as I can tell works, except that when I start the unit tests using mix test
, the application first uses the real “database” instead of the MockDatabase which is defined in test/test_helper.ex:
Code.require_file("test/mock_dets.ex") # Mocking dets with ets
Mox.defmock(MyApp.MockRequest, for: MyApp.Request)
Mox.defmock(MyApp.MockDatabase, for: MyApp.Database)
Application.put_env(:my_app, :use_delay, false)
Application.put_env(:my_app, :request, MyApp.MockRequest)
Application.put_env(:my_app, :database, MyApp.MockDatabase)
Application.put_env(:my_app, :dets, MyApp.MockDETS)
ExUnit.start()
When I run the unit tests, the Application is started before the Mox(s) are configured, and the real Database is used. What can I do to avoid this?
I’ve tried not starting the application with “–no-start” but this also stops the dependencies (like Mox) from starting.