3

I have a process builder which perform apex invocable action. Its working fine in dev sandbox and this are the components I have built: 1. Process Builder 2. Apex Invocable class (ProcessBuilderClass) 3. Associated test class (ProcessBuilderClass_Test)

When I run my test class in Dev sandbox, all test methods are pass. But, when I try to deploy to QA sandbox through change set where I include above components and when I validate by running my test class, it got failed.

Just for reference, here is my code:

Process Builder: My Process builder criteria: Whenever recordtype/stagename/ownerId of opportunity changes, it will call apex class. Which will update time stamp field on opportunity. And its active only Here is my class code:

public class TestTimeStampUpdate {   
@InvocableMethod
public static void UpdateTimeStamp(List<Id> opptyIds)
{
    List<Opportunity> oppList = new List<Opportunity>();
    for(Id oppId : opptyIds) {
        Opportunity opp = new Opportunity();
        opp.Id = oppId;
        opp.TestField__c = DateTime.now().getTime();
        oppList.add(opp);
    }
    if(!oppList.isEmpty()) {              
        update oppList;
    }
}    

}

Here are my test methods that are pass in dev sandbox, but not while deploying to QA:

@isTest
private class TestTimeStampUpdate_Test {
    static testMethod void TestMethod2() {
        test.startTest();
        Opportunity opp = getOpportunity(); // Insert and return opportuntiy
        opp.StageName = '2 - StageII';
        Decimal testTS = opp.TestField__c;
        update opp;        
        Opportunity oppRec = [SELECT id,TestField__c FROM Opportunity WHERE Id =: opp.Id];
        System.assert(oppRec.TestField__c > testTS);
        test.stopTest();
    }    
    static testMethod void TestMethod1() {
        test.startTest();
        Opportunity opp = getOpportunity();
        Decimal testTS = opp.TestField__c;        
        User usr = getUser();
        opp.OwnerId = usr.Id;
        update opp;        
        Opportunity oppRec = [SELECT id,TestField__c FROM Opportunity WHERE Id =: opp.Id];
        System.assert(oppRec.TestField__c > testTS);
        test.stopTest();
    } 
}

Please help me out where I am missing ? I really appreciate for your help.

  • Have you added all the reference fields/components used in Process Builder? As per Salesforce Doc, "If you plan to deploy a flow with change sets, consider limitations in migration support. Make sure your flows reference only fields and components that are available in change sets." – Devendra Oct 13 '16 at 16:59
8

Process builder deploys in an inactive state.

If test methods are written around its results snd this blocks your deployment you have the following options:

  1. Manually create the PB in production and activate it
  2. Comment out the system asserts in the test class
    • Deploy and activate the PB
    • Uncomment the asserts int he test class
    • Redeploy the test class

Also, be prepared for the test to still fail due to other processes in production that may not be in the sandbox. But at that point you can at least debug your code in production as long as the process is not a critical process that could affect day to day operations.

  • 1
    Thanks Eric, Looks like it's time for me to scrap the process builder. – Naresh Oct 13 '16 at 18:11
0

You need to call InvocableMethod method in your test class. Below changes will help to deploy your class:

    @isTest
    private class TestTimeStampUpdate_Test {
    static testMethod void TestMethod2() {

    Opportunity opp = getOpportunity(); // Insert and return opportuntiy
    opp.StageName = '2 - StageII';
    Decimal testTS = opp.TestField__c;
    update opp;

    List<Id> oppIds = new List<Id> ();
    for (Opportunity o : opp){
        oppIds.add(o.Id);
    }

    test.startTest();
        TestTimeStampUpdate.UpdateTimeStamp(oppIds);
    test.stopTest();       
    Opportunity oppRec = [SELECT id,TestField__c FROM Opportunity WHERE Id =: opp.Id];
    System.assert(oppRec.TestField__c > testTS);

}

static testMethod void TestMethod1() {

    Opportunity opp = getOpportunity();
    Decimal testTS = opp.TestField__c;        
    User usr = getUser();
    opp.OwnerId = usr.Id;
    update opp;        

    List<Id> oppIds1 = new List<Id> ();
    for (Opportunity o : opp){
        oppIds1.add(o.Id);
    }

    test.startTest();
        TestTimeStampUpdate.UpdateTimeStamp(oppIds1);
    test.stopTest();

    Opportunity oppRec = [SELECT id,TestField__c FROM Opportunity WHERE Id =: opp.Id];
    System.assert(oppRec.TestField__c > testTS);

} 
}
  • Can you add a bit more explanation? – Adrian Larson Oct 31 '17 at 0:47
  • When we deploy Process builder and Invocable Apex Class, Test Class Runs but Invocable method will not get called from Process builder. To eliminate that issue we have to Call invocable method in test class between test.StartTest() and test.Stop test() and pass the parameters. This will help to run the logic, and we have code coverage and passes assertion. – sfdc Oct 31 '17 at 16:02

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.