Skip to main content
deleted 15 characters in body
Source Link
Sagnik
  • 615
  • 4
  • 16
  • 39
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 = formulaacc.Id;
      con.LastName = 'test';
      updatedContactList.add(formulaSpecconc);
      updatedAccountList.add(formulaacc);
}
    
   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.startTest();
//Creating account
Account account = new Account();
Accountaccount.Name = 'test account';
Accountaccount.Rating = 'Hot';
Database.insert(formulaaccount);

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
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 = formula.Id;
      con.LastName = 'test';
      updatedContactList.add(formulaSpec);
      updatedAccountList.add(formula);
}
    
   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.startTest();
//Creating account
Account account = new Account();
Account.Name = 'test account';
Account.Rating = 'Hot';
Database.insert(formula);

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
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.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
added 2328 characters in body
Source Link
Sagnik
  • 615
  • 4
  • 16
  • 39

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 = formula.Id;
      con.LastName = 'test';
      updatedContactList.add(formulaSpec);
      updatedAccountList.add(formula);
}
    
   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(formula);

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.

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 = formula.Id;
      con.LastName = 'test';
      updatedContactList.add(formulaSpec);
      updatedAccountList.add(formula);
}
    
   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(formula);

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.

Source Link
Sagnik
  • 615
  • 4
  • 16
  • 39

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?