[SalesForce] Is it possible to check programmatically whether a process builder flow is active or not

I'm facing a unique problem while writing a test class for a class which is invoked by a process builder flow. First time, i wrote only test data and relied on the flows which would get triggered and hence the test class passed. But, when I tried moving this into a higher org (which didn't have any active version of the flow) and when the test classes run the one based on flow would fail since process builder flows gets deployed but their status remains deactivated. To fix this i called the specific methods on the class which gets invoked by the flow.

Now a new problem came up (flows deployed and activated now)that when I ran the test classes on higher org where the flows are now active then assertions would fail since technically 2 times the flow gets called. For the test class to pass now the only way is to deactivate the flow and then run the test class.

So, I was thinking if there's any way we can put a check on my test class if a flow is inactive then only call the method of the class explicitly(this class is the one which gets invoked by flow). Is this possible or is there any other workaround?

EDIT:
Sharing code for a scenario where on creation of an account with rating as 'Hot' a contact gets created under it automatically. A process builder with entry condition of rating equals 'Hot' had been written which calls a class with invocable method.

Class:

public with sharing class example{

//Using Invocable annotation so that method can be used by Process builder flow
@InvocableMethod(label = 'Insert Contact records' description='Insert Contact records by default on creation of Account record ') 

public static void insertContact(List<Id> accountId){

List<Contact> updatedContactList = new List<Contact>();
List<Account> updatedAccountList = new List<Account>();

for(Account acc : [SELECT Id FROM Account WHERE Id IN:accountId LIMIT : Limits.getLimitQueryRows() - Limits.getQueryRows()] ){

      Contact con = new Contact();
      con.AccountId = acc.Id;
      con.LastName = 'test';
      updatedContactList.add(conc);
      updatedAccountList.add(acc);
}

   Savepoint sp = Database.setSavepoint();
   try{
       if(updatedAccountList.size() > 0){
           Database.upsert(updatedAccountList);
       }
       if(updatedContactList.size() > 0){
           Database.insert(updatedContactList);
       }
   }

   catch(Exception e){
      Database.rollback(sp);
      system.debug('The exception is '+e);
    }
  }
}

Test class block:

Test.startTest();
//Creating account
Account account = new Account();
account.Name = 'test account';
account.Rating = 'Hot';
Database.insert(account);

Account accountInserted = [SELECT Id FROM Account LIMIT 1];

List<Id> accountIdList = new List<Id>();
accountIdList.add(accountInserted.Id);
example.insertContact(accountIdList);
Test.stopTest();

Contact contList=[SELECT Id FROM Contact];
System.assertEquals(1,contList.size()); // this would return 2 if flow is active causing test class to fail; if flow is inactive then this would pass

This is just a hypothetical scenario i'm taking to explain my problem. With process builder it is possible to insert a record without writing any code.

Best Answer

Never include process builder and whole apex implementation in one change set for Deployment, because process builder behaves in a different way as compared to workflow. Workflow remains active after deployment but we have to enable the process builder manually in target environment. There is some functionality in our test classes / Classes which is dependent on prcoess builder executions which will almost never work if we include process builder in the same change set as our apex implementation.

First include all your processes in one change set and deploy the same. Activate all processes in target env then deploy your apex.

Related Topic