Prerequisites:
- Tutorial #12: Apex Unit Tests
Now that you’ve added a schedulable class, you’ll also need to add a test method to ensure that your class has test coverage. In this lesson, you’ll add a test class with one test method, which calls System.Schedule to schedule the class.
You’ll switch to the Apex Classes page to create the test class since you’ll be running the tests from there.
- Click .
- In the code editor box, add the following test class.
@isTest private class TestSchedulableClass { // CRON expression: midnight on March 15. // Because this is a test, job executes // immediately after Test.stopTest(). public static String CRON_EXP = '0 0 0 15 3 ? 2022'; static testmethod void test() { Test.startTest(); // Schedule the test job String jobId = System.schedule('ScheduleApexClassTest', CRON_EXP, new MySchedulableClass()); // Get the information from the CronTrigger API object CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId]; // Verify the expressions are the same System.assertEquals(CRON_EXP, ct.CronExpression); // Verify the job has not run System.assertEquals(0, ct.TimesTriggered); // Verify the next time the job will run System.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime)); // Verify the scheduled job hasn't run yet. Merchandise__c[] ml = [SELECT Id FROM Merchandise__c WHERE Name = 'Scheduled Job Item']; System.assertEquals(ml.size(),0); Test.stopTest(); // Now that the scheduled job has executed after Test.stopTest(), // fetch the new merchandise that got added. ml = [SELECT Id FROM Merchandise__c WHERE Name = 'Scheduled Job Item']; System.assertEquals(ml.size(), 1); } }
- Click Save.
- Click Run Test to execute the test method.
Tell Me More...
- The test method schedules the MySchedulableClass class by calling the System.schedule method. The System.Schedulemethod takes three arguments: a name for the job, an expression used to represent the time and date the job is scheduled to run, and the name of the class. The System.schedule method uses the user's timezone for the basis of all schedules.
- The call to System.schedule is included within the Test.startTest and Test.stopTest block. This ensures that the job gets executed after the Test.stopTest call regardless of the schedule specified in the cron expression. Any asynchronous code included within Test.startTest and Test.stopTest gets executed synchronously after Test.stopTest.
- Finally, the test method verifies a new merchandise item got added by the scheduled class.
You say to use Test.startTest() and Test.stopTest() methods to wrap the call System.schedule() and that this cause the job to run. I tried this to test scheduling my job to send email. After the Test.stopTest() my job was still in the "WAITING" state. Here is my code:
ReplyDelete@isTest
private class SendReminderEmailScheduleTest {
static testmethod void test() {
Test.startTest();
// create a CRON schedule string
Datetime dt = Datetime.now().addMinutes(1);
String cron_schedule = '0 '+dt.minute()+' * '+dt.day()+' '+dt.month()+' ? '+dt.year();
// ask the system to create a job by scheduling our Appointment Reminder class
String jobId = System.schedule('SendReminderEmailScheduleTest',
cron_schedule,
new SendReminderEmailSchedule());
// Get the CronTrigger object for our job
CronTrigger ct = [SELECT Id, TimesTriggered, State FROM CronTrigger WHERE id = :jobId];
// Verify the job has not run
System.assertEquals(0, ct.TimesTriggered);
System.assertEquals('WAITING', ct.State);
// As we created the job while in "test mode," calling "stopTest()" will cause the job to run
Test.stopTest();
// Get the CronTrigger object for our job (again)
ct = [SELECT Id, TimesTriggered, State FROM CronTrigger WHERE id = :jobId];
// Verify the job has run
System.assertEquals(1, ct.TimesTriggered);
System.assertEquals('COMPLETE', ct.State);
// Is there some additional assert we can run to know the system has sent the emails?
}
}
The System.assertEquals(1, ct.TimesTriggered); FAILS with ct.TimesTriggered == 0
i have the same problem
ReplyDeleteArticles, on the other hand, can vary greatly in length depending on the publication and the topic at hand. Will Gojo Satoru Die In Jujutsu Kaisen? They can range from a few hundred to several thousand words, allowing for more in-depth exploration of complex subjects.
ReplyDelete