Helpers for testing AshOban triggers and scheduled actions.
Setup
Use this module in your test case to get all helpers at once:
defmodule MyApp.DataCase do
use ExUnit.CaseTemplate
using do
quote do
use AshOban.Test, repo: MyApp.Repo
end
end
enduse AshOban.Test accepts the same options as use Oban.Testing and
delegates to it, so you get both Oban's own testing helpers and AshOban's
helpers in a single call.
See the Testing Guide for full setup instructions.
Helpers
Running triggers
schedule_and_run_triggers/2 runs all matching jobs synchronously, which
is the most common thing you need in tests:
# Run all triggers for a resource
AshOban.Test.schedule_and_run_triggers(MyApp.MyResource)
# Run a specific trigger
AshOban.Test.schedule_and_run_triggers({MyApp.MyResource, :process})
assert %{success: 1, failure: 0} =
AshOban.Test.schedule_and_run_triggers(MyApp.MyResource)Asserting enqueued jobs
After an action that calls run_oban_trigger, use assert_triggered/3 to
verify the job was enqueued for the right record:
{:ok, appointment} = Appointment.update(appointment, params)
assert_triggered(appointment, :create_zoom_meeting)These are macros that require all_enqueued/1 to be in scope (provided
by use AshOban.Test or use Oban.Testing directly).
Asserting scheduler eligibility
Use assert_would_schedule/3 and refute_would_schedule/3 to check whether
a record's current state matches a trigger's where filter without running
the scheduler:
record = MyApp.create_record!()
assert_would_schedule(record, :process)
processed = MyApp.process!(record)
refute_would_schedule(processed, :process)
Summary
Functions
Sets up AshOban test helpers.
Asserts that an Oban job has been enqueued for the given record and trigger.
Asserts that the given record currently matches a trigger's where filter,
meaning the scheduler would enqueue a job for it if it ran now.
Refutes that an Oban job has been enqueued for the given record and trigger.
Refutes that the given record currently matches a trigger's where filter.
Schedules and runs triggers, draining queues by default.
Functions
Sets up AshOban test helpers.
Delegates to use Oban.Testing so Oban's own helpers (all_enqueued,
assert_enqueued, etc.) are also available. Accepts the same options.
Options
:repo- Required. The Ecto repo to use for querying Oban jobs.:prefix- The database prefix for Oban tables. Defaults to"public".
Example
use AshOban.Test, repo: MyApp.Repo, prefix: "private"
Asserts that an Oban job has been enqueued for the given record and trigger.
Returns the list of matching Oban.Job structs so you can make further
assertions on job properties if needed.
Requires all_enqueued/1 to be in scope — use use AshOban.Test or
use Oban.Testing to set this up.
Options
Additional options are merged with the trigger-derived options (:worker,
:args) and forwarded to all_enqueued/1. Use these to narrow the
assertion:
:queue- assert the job is in a specific queue:state- assert the job is in a specific state:priority- assert the job has a specific priority
Examples
{:ok, appointment} = Appointment.update(appointment, params)
assert_triggered(appointment, :create_zoom_meeting)
# Narrow to a specific queue
assert_triggered(appointment, :create_zoom_meeting, queue: :zoom_api)
# Further assert on the returned jobs
[job] = assert_triggered(appointment, :create_zoom_meeting)
assert job.priority == 2
Asserts that the given record currently matches a trigger's where filter,
meaning the scheduler would enqueue a job for it if it ran now.
This does not check whether a job has already been enqueued — use
assert_triggered/3 for that. Instead, it checks the record's current
state in the database against the trigger's filter expression.
Returns the matched record.
Options
:actor- The actor to use when reading the record. Defaults tonil.:tenant- The tenant to use when reading the record. Defaults tonil.:domain- The domain to use when reading. Defaults to the resource's configured Oban domain.
Examples
# After creating a record, assert it is eligible for scheduling
record = MyApp.create_record!()
assert_would_schedule(record, :process)
# After processing, assert it is no longer eligible
processed = MyApp.process!(record)
refute_would_schedule(processed, :process)
Refutes that an Oban job has been enqueued for the given record and trigger.
Requires all_enqueued/1 to be in scope — use use AshOban.Test or
use Oban.Testing to set this up.
Options
Additional options are merged with the trigger-derived options (:worker,
:args) and forwarded to all_enqueued/1. Use these to narrow the
assertion:
:queue- refute that the job is in a specific queue:state- refute that the job is in a specific state:priority- refute that the job has a specific priority
Examples
refute_triggered(appointment, :create_zoom_meeting)
# Narrow to a specific queue
refute_triggered(appointment, :create_zoom_meeting, queue: :zoom_api)
Refutes that the given record currently matches a trigger's where filter.
This is the inverse of assert_would_schedule/3. It asserts that the
scheduler would not enqueue a job for the record if it ran now.
Options
:actor- The actor to use when reading the record. Defaults tonil.:tenant- The tenant to use when reading the record. Defaults tonil.:domain- The domain to use when reading. Defaults to the resource's configured Oban domain.
Examples
processed = MyApp.process!(record)
refute_would_schedule(processed, :process)
Schedules and runs triggers, draining queues by default.
This is a wrapper around AshOban.schedule_and_run_triggers/2 with
drain_queues?: true set by default, making it suitable for use in tests
where you want jobs to execute synchronously.
Arguments
resources_or_domains_or_otp_apps- Can be any of the following:- A resource module - runs all triggers for that resource
- A
{resource, :trigger_name}tuple - runs a specific trigger - A domain module - runs all triggers for all resources in that domain
- An OTP app atom - runs all triggers for all domains in that app
- A list of any of the above
Options
:drain_queues?- Whether to drain queues after scheduling. Defaults totrue(unlikeAshOban.schedule_and_run_triggers/2which defaults tofalse).:scheduled_actions?- Whether to include scheduled actions. Defaults tofalse. When passing a{resource, :scheduled_action_name}tuple this is automatically enabled.:triggers?- Whether to include triggers. Defaults totrue.:actor- The actor to pass to the trigger actions. Requires an actor persister to be configured.:oban- The Oban instance to use. Defaults toOban.:queue- Passed through toOban.drain_queue/2.:with_limit- Passed through toOban.drain_queue/2.:with_recursion- Passed through toOban.drain_queue/2.:with_safety- Passed through toOban.drain_queue/2.:with_scheduled- Passed through toOban.drain_queue/2.
Return Value
Returns a map with job outcome counts:
%{
success: non_neg_integer(),
failure: non_neg_integer(),
discard: non_neg_integer(),
cancelled: non_neg_integer(),
snoozed: non_neg_integer(),
queues_not_drained: [atom()]
}Examples
# Run all triggers for a resource and assert outcomes
assert %{success: 3, failure: 0} =
AshOban.Test.schedule_and_run_triggers(MyResource)
# Run a specific trigger with an actor
assert %{success: 2} =
AshOban.Test.schedule_and_run_triggers({MyResource, :process},
actor: %MyApp.User{id: 1}
)