This question definitely is a duplicate of many questions here, but after reading most of them I am still somewhat clueless.
Question 1: why I can't just catch exceptions in the execute and send an email out? Would a) Batch help, or b) checking or c) writing a custom Error object?
public class MyQueue implements Queueable, Database.AllowsCallouts {
public void execute(QueueableContext context) {
try {
Integer invalid = 100 / 0;
}
catch(Exception ex) {
sendEmail(ex);
}
}
}
Question 2: Can I test it like this?
@IsTest
private class MyQueue_Test {
@IsTest
private static void sendsEmailOnError() {
// Exercise
Test.startTest();
System.enqueueJob(new MyQueue());
Test.stopTest();
// Verify
System.assertEquals(1, Limits. getEmailInvocations());
}
}
Best Answer
The problem is that Test.stopTest executes the asynchronous code, then resets the governor limits back to the state it was in immediately before Test.startTest is called. If you really wanted to verify the output, you'd need a static method to check:
And from there, test it in your unit test:
This is one of those relatively rare conditions where the easiest way to perform a task is to inject test code to the actual code. You should do this minimally, of course, but as often as necessary.
Alternatively, a more idiomatic way to do this would be to use the Stub API. The idea here is that you'd mock out sendEmail by overriding it in the unit test. This is a bit complicated to use in practice, especially since you only need to add two lines of code.