0

I am trying to write a unit test for a trigger handler method that enqueues a queueable class. I am using ApexMocks to write the unit test for this trigger method. https://github.com/financialforcedev/fflib-apex-mocks

For example , my class looks like this:

    public with sharing class DividingLogic implements Queueable {
      public String recId;

      public DividingLogic(String recId){

      }

      public void execute(QueueableContext recId){
        // calls a static method of another class

      }
}

I know that Queueable and QueueableContext both are interfaces that are part of Salesforce and I think I can use them in generating ApexMocks class. So I got started with below testing. I am trying to test if the DividingLogic class gets called once from the trigger method. I plan to check that using mock.verify() method.

public void testmethod afterInsertTest(){

    // Given
    fflib_ApexMocks mocks = new fflib_ApexMocks();
    Queueable mockQueue = (Queueable)mocks.mock(DividingLogic.class);

// When
// I am wondering how would I pass the QueueableContext here
// How do I call the execute() method of Queueable


// Then
// I want to check whether the class was enqueued from the trigger
// or called at only 1 time from the trigger. 
// ((Queueable)mocks.verify(mockQueue,1).execute(); ??


}

appreciate any insights and suggestions?

2

Good to see an apexMocks user -

The matcher to use for QueueableContext would be (QueuableContext)fflib_Match.anyObject() - that said, I'll be surprised if the StubProvider interface upon which ApexMocks is built will support queueables

If it works at all ...

// Given 
fflib_ApexMocks mocks = new fflib_ApexMocks();
Queueable mockQueue = (Queueable)mocks.mock(DividingLogic.class);

// When the queueable is added
Test.startTest();
insert new Foo__c(...); // does the System.enqueueJob
Test.stopTest();  // async executes here

// Then Verify the queueable was invoked exactly once
((Queueable) mocks.verify(mockQueue,mocks
                          .times(1)
                          .description('Queueable should start')
     ))
     .execute((QueueableContext)fflib_Match.anyObject()); 

An alternate approach to explore in lieu of ApexMocks would be to see if the AsyncApexJob with JobType = Queueable is created after

Test.startTest();
insert new Foo__c(...); // does the System.enqueueJob
Test.stopTest();  // async executes here
| improve this answer | |
  • Great thanks! I am trying to see if I can avoid inserting any record using Insert as that will involve Database interaction. Hence I used fflib_IDGenerator.cls class to create Ids that I can pass to execute method. Does that approach sound good? I probably leaning towards your first solution using apexMocks. The second approach of yours would require me to use the Insert operation for sure. – SfdcBat Jan 20 '18 at 23:25
  • By the way , the first approach compiled and ran successfully. When I ran the testmethod it failed with an error : fflib_ApexMocksException Expect 1, Actual 0 -- Wanted but not invoked: DividingLogic__sfdc_ApexStub.execute(System.QueueableContext). Queueable should start. . I am doing TDD. So I think once I implement the logic to enqueue DividingLogic Class from the trigger handler method then the test would eventually pass. – SfdcBat Jan 20 '18 at 23:36
  • Thanks much! My above assumption is not correct it seems. Even after putting the Queueable class in handler method the test method fails with same error. I have create a new question in the forum for the same. – SfdcBat Jan 21 '18 at 0:25
  • To avoid the trigger insert you have to use a class that does the system.enqueuejob and invoke that class in the testmethod. @SfdcBat – cropredy Jan 21 '18 at 3:24
  • Thanks if you see my new question that I posted , I call the method in that. I feel that using ApexMock to verify that the job is enqueued is not the appropriate option here. Instead querying for AsyncApexJob and doing assertion that one AsyncApexJob is present is the correct approach. Let me know if you think otherwise. – SfdcBat Jan 21 '18 at 3:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.