Skip to content

Commit 8d0748e

Browse files
Rewrite Testing Jobs section [ci-skip]
This simplifies the prose and code examples, and links to more API docs.
1 parent 4230d0d commit 8d0748e

File tree

1 file changed

+31
-34
lines changed

1 file changed

+31
-34
lines changed

guides/source/testing.md

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,20 +2074,21 @@ NOTE: The `assert_emails` method is not tied to a particular deliver method and
20742074
Testing Jobs
20752075
------------
20762076

2077-
Since your custom jobs can be queued at different levels inside your application,
2078-
you'll need to test both the jobs themselves (their behavior when they get enqueued)
2079-
and that other entities correctly enqueue them.
2077+
Jobs can be tested in isolation (focusing on the job's behavior) and in context
2078+
(focusing on the calling code's behavior).
20802079

2081-
### A Basic Test Case
2080+
### Testing Jobs in Isolation
20822081

2083-
By default, when you generate a job, an associated test will be generated as well
2084-
under the `test/jobs` directory. Here's an example test with a billing job:
2082+
When you generate a job, an associated test file will also be generated in the
2083+
`test/jobs` directory.
2084+
2085+
Here is an example test for a billing job:
20852086

20862087
```ruby
20872088
require "test_helper"
20882089
20892090
class BillingJobTest < ActiveJob::TestCase
2090-
test "that account is charged" do
2091+
test "account is charged" do
20912092
perform_enqueued_jobs do
20922093
BillingJob.perform_later(account, product)
20932094
end
@@ -2096,52 +2097,48 @@ class BillingJobTest < ActiveJob::TestCase
20962097
end
20972098
```
20982099

2099-
This test is pretty simple and only asserts that the job did work that was expected. You can also use `perform_now` to run the job inline, but if you have retries configured, any exceptions raised by the job will be silently ignored, whereas `perform_enqueued_jobs` will fail the test and print the exception information.
2100+
The default queue adapter for tests will not perform jobs until
2101+
[`perform_enqueued_jobs`][] is called. Additionally, it will clear all jobs
2102+
before each test is run so that tests do not interfere with each other.
2103+
2104+
The test uses `perform_enqueued_jobs` and [`perform_later`][] instead of
2105+
[`perform_now`][] so that if retries are configured, retry failures are caught
2106+
by the test instead of being re-enqueued and ignored.
21002107

2101-
### Custom Assertions and Testing Jobs inside Other Components
2108+
[`perform_enqueued_jobs`]: https://api.rubyonrails.org/classes/ActiveJob/TestHelper.html#method-i-perform_enqueued_jobs
2109+
[`perform_later`]: https://api.rubyonrails.org/classes/ActiveJob/Enqueuing/ClassMethods.html#method-i-perform_later
2110+
[`perform_now`]: https://api.rubyonrails.org/classes/ActiveJob/Execution/ClassMethods.html#method-i-perform_now
21022111

2103-
Active Job ships with a bunch of custom assertions that can be used to lessen the verbosity of tests. For a full list of available assertions, see the API documentation for [`ActiveJob::TestHelper`](https://api.rubyonrails.org/classes/ActiveJob/TestHelper.html).
2112+
### Testing Jobs in Context
21042113

2105-
It's a good practice to ensure that your jobs correctly get enqueued or performed
2106-
wherever you invoke them (e.g. inside your controllers). This is precisely where
2107-
the custom assertions provided by Active Job are pretty useful. For instance,
2108-
within a model, you could confirm that a job was enqueued:
2114+
It's good practice to test that jobs are correctly enqueued, for example, by a
2115+
controller action. The [`ActiveJob::TestHelper`][] module provides several
2116+
methods that can help with this, such as [`assert_enqueued_with`][].
2117+
2118+
Here is an example that tests an account model method:
21092119

21102120
```ruby
21112121
require "test_helper"
21122122
2113-
class ProductTest < ActiveSupport::TestCase
2123+
class AccountTest < ActiveSupport::TestCase
21142124
include ActiveJob::TestHelper
21152125
2116-
test "billing job scheduling" do
2126+
test "#charge_for enqueues billing job" do
21172127
assert_enqueued_with(job: BillingJob) do
2118-
product.charge(account)
2128+
account.charge_for(product)
21192129
end
2120-
assert_not account.reload.charged_for?(product)
2121-
end
2122-
end
2123-
```
21242130
2125-
The default adapter, `:test`, does not perform jobs when they are enqueued.
2126-
You have to tell it when you want jobs to be performed:
2131+
assert_not account.reload.charged_for?(product)
21272132
2128-
```ruby
2129-
require "test_helper"
2133+
perform_enqueued_jobs
21302134
2131-
class ProductTest < ActiveSupport::TestCase
2132-
include ActiveJob::TestHelper
2133-
2134-
test "billing job scheduling" do
2135-
perform_enqueued_jobs(only: BillingJob) do
2136-
product.charge(account)
2137-
end
21382135
assert account.reload.charged_for?(product)
21392136
end
21402137
end
21412138
```
21422139

2143-
All previously performed and enqueued jobs are cleared before any test runs,
2144-
so you can safely assume that no jobs have already been executed in the scope of each test.
2140+
[`ActiveJob::TestHelper`]: https://api.rubyonrails.org/classes/ActiveJob/TestHelper.html
2141+
[`assert_enqueued_with`]: https://api.rubyonrails.org/classes/ActiveJob/TestHelper.html#method-i-assert_enqueued_with
21452142

21462143
### Testing that Exceptions are Raised
21472144

0 commit comments

Comments
 (0)