mirror of https://github.com/rails/rails
Update job testing guidelines
The current example test for jobs using `perform_now` to run the job inline. This is problematic for jobs that have retries configured, as any exception that is retried will be silently rescued. Ideally, the test will still fail because the job did not perform the work it was supposed to, but it makes finding the root cause a lot harder. Testing with `perform_enqueued_jobs` and `perform_later` gets around this problem, as the retries are also performed immediately and, assuming that the exception happens consistently, it will bubble up after exhausting its retries. Therefore, this PR updates the basic test guidance to suggest `perform_enqueued_jobs` and `perform_later` over `perform_now`. Both described behaviours make it harder to test that a job raises a specific exception, so this requires special handling, which I added a paragraph on. I can pull that out to a separate PR if desired.
This commit is contained in:
parent
5cf742ef51
commit
315db730cc
|
@ -1929,13 +1929,15 @@ require "test_helper"
|
|||
|
||||
class BillingJobTest < ActiveJob::TestCase
|
||||
test "that account is charged" do
|
||||
BillingJob.perform_now(account, product)
|
||||
perform_enqueued_jobs do
|
||||
BillingJob.perform_later(account, product)
|
||||
end
|
||||
assert account.reload.charged_for?(product)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
This test is pretty simple and only asserts that the job did work that was expected.
|
||||
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.
|
||||
|
||||
### Custom Assertions and Testing Jobs inside Other Components
|
||||
|
||||
|
@ -1982,6 +1984,25 @@ end
|
|||
All previously performed and enqueued jobs are cleared before any test runs,
|
||||
so you can safely assume that no jobs have already been executed in the scope of each test.
|
||||
|
||||
### Testing that Exceptions are Raised
|
||||
|
||||
Testing that your job raises an exception in certain cases can be tricky, especially when you have retries configured. The `perform_enqueued_jobs` helper fails any test where a job raises an exception, so to have the test succeed when the exception is raised you have call the job's `perform` method directly.
|
||||
|
||||
```ruby
|
||||
require "test_helper"
|
||||
|
||||
class BillingJobTest < ActiveJob::TestCase
|
||||
test "does not charge accounts with insufficient funds" do
|
||||
assert_raises(InsufficientFundsError) do
|
||||
BillingJob.new(empty_account, product).perform
|
||||
end
|
||||
refute account.reload.charged_for?(product)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
This method is not recommended in general, as it circumvents some parts of the framework, such as argument serialization.
|
||||
|
||||
Testing Action Cable
|
||||
--------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue