4

Given an @future method

public class MyClass {
  @future
  public static void doPublishAsFuture(){
    EventBus.publish(new My_Platform_Event__e());
  }
}

and a testmethod

@isTest
private static void testPlatEventPublishViaFuture() {
  Test.startTest();
  MyClass.doPublishAsFuture();
  Test.stoptest();
  // How to know if event(s) were published?
  System.assertEquals(1,Limits.getDmlRows()); // fails, actual value = 0!
}

So, assuming I don't have (or want) a trigger to consume the Platform Event and save in some Log__c SObject, how do I verify the Platform Events were actually published?

N.B. recording in a static variable within the class that the publish was successful and interrogating in the testmethod does not seem like a great solution.

  • Just curious, why would you publish them from a future? Also, it should consume a DML. Maybe it's similar to this question. – Adrian Larson Sep 7 '17 at 22:10
  • @AdrianLarson - (1) yes, publishing PlatformEvents does consume DML but the limits are reset after Test.stopTest() - which is needed to start the @future so the value is not assertable. (2) PlatformEvents are not part of a transaction so it would seem that best practice would be to publish at the end of the transaction - and the future would never execute if the transaction aborted. (3) I'm using future as a fallback in case queueables are exhausted – cropredy Sep 7 '17 at 22:19
  • Without platform level support for mocking Platform Events I suspect an Apex trigger is the only way to interact with them in a testing context. – Daniel Ballinger Sep 8 '17 at 2:48
  • I've raised it on the Platform Events success community group. If you don't care about the Database.SaveResult you could just maintain your own static count ever time EventBus.publish is called. It's not pretty, but should work. – Daniel Ballinger Sep 8 '17 at 2:56
0

Couldn't you validate it within the future method?

I hate putting test validation in classes, but if you need it absolutely....

if( test.isRunningTest() ){
    System.assertEquals( 1, Limits.getDmlRows() );
}

It would only execute within a test instance, so shouldn't affect your code execution otherwise. I just don't like it because I think it is dirty coding.

| improve this answer | |
  • Thanks -- that said, I would never put validation within the class; besides this doesn't prove that the future method was ever invoked and that it published a Platform Event. Daniel Ballinger's last comment is a better solution and one I considered but classes shouldn't have to register their action in a static variable for inspection by the testmethod. – cropredy Sep 9 '17 at 22:44

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.