View Source Introduction to Testing

Automated testing is an essential component of building reliable, long-lived applications. Oban orchestrates your application's background tasks, so naturally, testing Oban is highly recommended.

Setup Application Config

Ensure your app is configured for testing before you begin running tests.

There are two testing modes available:

  • :inline—jobs execute immediately within the calling process and without touching the database. This mode is simple and may not be suitable for apps with complex jobs.
  • :manual—jobs are inserted into the database where they can be verified and executed when desired. This mode is more advanced and trades simplicity for flexibility.

If you're just starting out, :inline mode is recommended:

config :my_app, Oban, testing: :inline

For more complex applications, or if you'd like complete control over when jobs run, then use :manual mode instead:

config :my_app, Oban, testing: :manual

Both testing modes prevent Oban from running any database queries in the background. This simultaneously prevents Sandbox errors from plugin queries and prevents queues from executing jobs unexpectedly.

Changing Testing Modes

Once the application starts in a particular testing mode it can't be changed. That's inconvenient if you're running in :inline mode and don't want a particular job to execute inline! Oban.Testing provides a helper to temporarily change testing modes within the context of a function.

For example, to switch to :manual mode when Oban is configured for :inline testing:

Oban.Testing.with_testing_mode(:manual, fn ->
  Oban.insert(MyWorker.new(%{id: 123}))

  assert_enqueued worker: MyWorker, args: %{id: 123}
end)

Or vice-versa, switch to :inline mode when the application is configured for :manual mode:

Oban.Testing.with_testing_mode(:inline, fn ->
  {:ok, %Job{state: "completed"}} = Oban.insert(MyWorker.new(%{id: 123}))
end)

Setup Testing Helpers

Oban provides helpers to facilitate manual testing. These helpers handle the boilerplate of making assertions on which jobs are enqueued.

The most convenient way to use the helpers is to use the module within your test case:

defmodule MyApp.Case do
  use ExUnit.CaseTemplate

  using do
    quote do
      use Oban.Testing, repo: MyApp.Repo
    end
  end
end

Alternatively, you can use the testing module in individual tests if you'd prefer not to include helpers in every test.

defmodule MyApp.WorkerTest do
  use MyApp.Case, async: true

  use Oban.Testing, repo: MyApp.Repo
end

Whichever way you choose, using use Oban.Testing requires the repo option because it's injected into many of the generated helpers.

If you are using isolation with namespaces through PostgreSQL schemas (Ecto "prefixes"), you can also specify this prefix when using Oban.Testing:

use Oban.Testing, repo: MyApp.Repo, prefix: "private"

With Oban configured for testing and helpers in the appropriate places, you're ready for testing. Learn about unit testing with Testing Workers, integration testing with Testing Queues, or prepare for production with Testing Config.