2

We have custom object CustomObject__c and platform event Platform_Event__e. Whenever any of CustomObject__c records are modified, platform event should be published. We need to write test class to cover the trigger but it is hard to think up an assert statement for such test class method.

trigger CustomObject on CustomObject__c (after update) {
    EventBus.publish(new Platform_Event__e());
}

@isTest private class CustomObjectTriggerTest {
    static testMethod void testTrigger() {
        CustomObject__c rec = new CustomObject__c(Name = 'A');
        Test.startTest();
            rec.Name = 'b';
            update rec;
        Test.stopTest();
        //System.assert( ... ??? Is there anything here we can assert? )
    }
}
  • The fact you are publishing this event from a trigger is completely irrelevant to your question. Your essential question seems to be how to cover any method which results in an event being published, which is more general. – Adrian Larson Jan 16 '18 at 16:39
  • if your platform event is consumed by a trigger, and the trigger updates some sobject, you can verify that way - but otherwise, this problem is not directly solvable except through indirect means such as your answer. I believe (safe harbor) that SFDC is addressing this – cropredy Jan 16 '18 at 20:24
  • @AdrianLarson yes, the question is about covering method which only publishes a platform event without side effects – Patlatus Jan 17 '18 at 10:16
  • 1
    @cropredy In my case platform event is not consumed by another trigger but by Lightning component, so platform event publishing doesn't have any side effects, which means there are no other object update. – Patlatus Jan 17 '18 at 11:01
7

My colleague suggested the following solution. Events can be stacked in static property and then checked in assert.

So trigger can be refactored like following

trigger CustomObject on CustomObject__c (after update) {
    CustomObjectService.publishEvent();
}

and method can be extracted into service class

public class CustomObjectService {
    @testVisible private static List<Platform_Event__e> eventList = new List<Platform_Event__e>();
    public static void publishEvent() {
        Platform_Event__e eve = new Platform_Event__e();
        eventList.add(eve);
        EventBus.publish(eve);
    }
}

and test for trigger can be rewritten in the following form

@isTest private class CustomObjectTriggerTest {
    static testMethod void testTrigger() {
        CustomObject__c rec = new CustomObject__c(Name = 'A');
        insert rec;
        Test.startTest();
            rec.Name = 'b';
            update rec;
        Test.stopTest();
        System.assert( 1, CustomObjectService.eventList.size(), 'There should be one element in the list' );
    }
}
0

My suggestion would be to 'instrument' the EventBus.publish method by creating a wrapper like so:

public class EventBusInstr {
public static List<SObject> events = new List<SObject>();
public static void publish(SObject event) {
   events.add(event);
   EventBus.publish(event);
  }
}

Next, use this wrapper instead of the built-in EventBus.publish method in your code:

CustomEvent__e event = new CustomEvent__e(Name__c = 'Custom');    
EventBusInstr.publish(event);

And finally, assert the number of events your wrapper publishes like so:

System.assert(EventBusInstr.events.size() == 1);
  • More traditionally this would be called a decorator pattern. – Adrian Larson Aug 17 at 17:04

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.