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.

4
  • 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
    Commented Sep 7, 2017 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
    Commented Sep 7, 2017 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. Commented Sep 8, 2017 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. Commented Sep 8, 2017 at 2:56

1 Answer 1

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.

1
  • 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
    Commented Sep 9, 2017 at 22:44

You must log in to answer this question.

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