2

I have a setup where a platform event is being created by a flow. I am using an apex trigger to subscribe to the platform event. The action being taken is using the ConnectAPIHelper to create a chatter notification that at mentions the triggering user.

I am using platform events so we can apply a Platform Event Subscriber Config to force the automation to run as system user. We need the chatter notification created as another user so that the @mentioned user receives an alert that they've been tagged (users don't receive alerts for tagging themselves).

This set up works as expected when I manually test it in the browser. However, when I am unit testing, the Platform Event Subscriber Config is not applying. I've tried downgrading the API on the trigger (v55 to v54), rebuilding the whole thing, deleting the PESC and recreating it. I'm still getting the same results. I also tried System.runAs, but in each scenario, the Automated Process user is executing the trigger and not my intended user. This is an issue because the autoproc user is not allowed to use the ConnectAPI, which causes me to be unable to test this functionality.

I did see this post Is there a way to force a Platform Event Trigger to honor the PlatformEventSubscriberConfig in unit tests? , but looks like poster took a different approach to get around the issue.

What am I missing?

Trigger

trigger ChatterNotificationTrigger on Chatter_Notification__e (after insert) {
    system.debug('*** current running user: ' + UserInfo.getUserId());

    for(Chatter_Notification__e chatterNotification : Trigger.new) {
        ConnectApi.FeedItem fi = (ConnectApi.FeedItem) ConnectApiHelper.postFeedItemWithMentions(null, chatterNotification.Target_ID__c, chatterNotification.Message__c);
    }
}

Unit Test

@isTest(SeeAllData=true)
public class ChatterNotificationTriggerTest {
    
    @isTest(SeeAllData=true) 
    static void verifyPostPublished() {
        Account account = [SELECT Id, OwnerId FROM Account LIMIT 1];
        List<AccountFeed> feedItems = [SELECT Id FROM AccountFeed WHERE ParentId = :account.Id];
        Integer startingCount = feedItems.size();
        system.debug('Starting count: ' + startingCount + ' | accountId: ' + account.Id);

        Test.startTest();
                List<Chatter_Notification__e> chatterNotifications = new List<Chatter_Notification__e>();
                    chatterNotifications.add(new Chatter_Notification__e(Target_ID__c = account.Id, Message__c = '<b>This</b> is a test to tag {' + account.OwnerId + '}.'));
                    chatterNotifications.add(new Chatter_Notification__e(Target_ID__c = account.Id, Message__c = '{' + account.OwnerId + '} Please follow up with this test'));
                    chatterNotifications.add(new Chatter_Notification__e(Target_ID__c = account.Id, Message__c = '{' + account.OwnerId + '} Please follow up with this test'));   

                List<Database.SaveResult> saveResults = Eventbus.publish(chatterNotifications);
                Test.getEventBus().deliver();           

            feedItems = [SELECT Id FROM AccountFeed WHERE ParentId = :account.Id];
            system.debug('Ending count: ' + feedItems.size());
            system.assertEquals(3, startingCount - feedItems.size());           
        Test.stopTest();    
    }
}

Platform Event Subscriber Config

<?xml version="1.0" encoding="UTF-8"?>
<PlatformEventSubscriberConfig xmlns="http://soap.sforce.com/2006/04/metadata">
    <platformEventConsumer>ChatterNotificationTrigger</platformEventConsumer>
    <batchSize>2000</batchSize>
    <masterLabel>ChatterNotificationTriggerConfig</masterLabel>
    <user>[email protected]</user>
    <isProtected>false</isProtected>
</PlatformEventSubscriberConfig>
2
  • As per the posting you reference, made by Derek F, this appears to be a limitation or bug in the Salesforce unit testing infrastructure. I suggest you do what Derek said he didn't do - raise a support case with Salesforce...
    – Phil W
    Commented Dec 7, 2022 at 15:43
  • I have logged a case, but this org doesn't have dev support. My chances of getting a response from them are slim. Commented Dec 7, 2022 at 15:49

2 Answers 2

1

The way I would work around this is as follows

  • Change your trigger to use a service layer class that does the ConnectAPI
  • In your testmethod, mock the service layer class with your own mock class that just confirms it was called with the proper arguments. This will allow the trigger to pass code coverage requirements as well as verifying its service class was invoked.
  • Then write normal unit test methods for the production service class using a System.runAs(..)

Techniques for mocking service classes - Personally, I use the fflib pattern and ApexMocks but there are other solutions. They all require a factory to create instances of a service class as well as a way to tell the factory to use a dependency-injected mock from the testmethod.

Reference: Salesforce Lightning Platform Enterprise Architecture 3rd Edition by Andy Fawcett, chapter on unit testing

2
  • For now, there is a test class that comes with just the ConnectApiHelper that has me covered from a functionality standpoint and I could just comment out the asserts in my unit test above to get coverage on the trigger. I just feel dirty doing an implicit assumption. I've got to sit down and digest the new info you've provided as that's a significant pattern change. Commented Dec 7, 2022 at 21:03
  • One of the advantages of the fflib pattern when wholesale adopted is that you have a framework that is amenable to dependency-injection to work around these knotty unit test edge cases while still doing proper unit tests (i.e. not commenting out asserts). Furthermore, it allows mocking of queries and DML so your unit tests run faster. It is a big step, I'll acknowledge, but one that has proven its worth to me over the last 9 years of SFDC work.
    – cropredy
    Commented Dec 8, 2022 at 0:23
1

Got a response back from salesforce support - this has been identified as a bug on their end and referred me to this known issue link: PlatformEventSubscriberConfig - Configured trigger’s running user in PlatformEventSubscriberConfig is ignored in Apex Test contexts

1
  • Still no action taken on it :-(
    – MikeA
    Commented Mar 22 at 17:12

You must log in to answer this question.

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