3

I have daily job that makes callouts and updates some records. There is @future method invocation in execute() method. I have created test according to this guide: https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_scheduling_2.htm

I can see in logs that my schedulable job started, but future method was not covered.

3 Answers 3

2

You don't include any of your code, so am taking a bit of a stab here at answering your question. Normally, all @future and schedulable code runs when the test.stopTest() method is called. You should be able to query for your schedulable job in the chronTrigger object to find the number of times it's been run which allows you to assert that your job ran, plus assert the results of the code. The latter should also allow you to assert that the @future method was called in the schedulable job.

2

Take a look at these guides that define testing @future methods:

  1. https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_invoking_future_methods.htm
  2. https://developer.salesforce.com/forums/?id=906F00000008wjuIAA

Essentially what you are going to want to do is to test the scheduled job's main methods, and then on a different test (or the same one but that would be a bit cluttered) you'd test the @future method.

If your @future method is contained within the execute method, I would suggest separating them so that you can call the @future method from another class.

Remember that @future makes a method run asynchronously in the background and on it's own thread, so testing it in its own test method will not hurt. If your @future method is the method that is making callouts, make sure you read up on how to mock callouts in tests.

global class ExampleSchedulable implements Schedulable {
   global void execute(SchedulableContext SC){
      executeFuture();
   }

   @future
   global String executeFuture(){
      return null;
   }
}

and then

@isTest
...
static testMethod void testFuture(){
   Test.startTest();
   class.executeFuture();
   Test.stopTest();
}

This might be an irrelevant answer, however, because it is difficult to determine your problem without seeing any code.

4
  • I can test @future method separately, but I am curious if I can include schedulable job to whole test case Commented Jun 16, 2016 at 14:00
  • From my knowledge there is no way to test an @future method within a trigger or scheduled class/batch. You have to test it separately. Here's a similar thread: salesforce.stackexchange.com/questions/61239/… Commented Jun 16, 2016 at 14:04
  • There is a way to test @future method that is invoked in trigger. I have done it before. You just have to do dml operation within Test.startTest() and Test.stptTest(). This will execute your code in separate execution context. After Test.stopTest() you can select records to do assertions. Commented Jun 16, 2016 at 14:11
  • 1
    @VladyslavKushney The difference is that a trigger runs in the context between test.startTest() and test.stopTest(). A Schedulable does not. There's no test.stopTest() following the schedulable's execution to cause the at future to also execute in a separate "test context".
    – crmprogdev
    Commented Jun 16, 2016 at 14:58
0

Konnor McDowell's answer is the better one. If a schedulable class calls a @future method the @future method will not be covered. If your schedulable class is simple and only calls the @future method, you can definitely include it all in one test. Just set up your mock as usual and within the start and stop test first call the mock class, then your schedulable, then your @future.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .