Saturday, 13 June 2015

Intro to Unit Test Data Creation Framework continued…….

In my last blog I gave examples of how the framework can be used. I also introduced rapidProcessing. Now we will expand the framework making use of rapidProcessing.

            rapidProcessing allows you to bypass the code in triggers, allowing the test            data to be created much faster ( this can also be useful when you are migrating          data into Salesforce ). In both of these situations you are telling Salesforce         exactly what data to create and you don't want the system to manipulate the          data further or to perform any actions within the triggers that may do all kind    of things such as creating additional business process data like Tasks, Events           and Cases etc, or sending out emails to customers etc ( however the latter wont             happen in unit tests as emails are not sent from unit tests ).

Lets take our previous example which will bypass both the Account and Contact triggers:

KeyValue[] kvsA = new KeyValue[]{};
KeyValue[] kvsC = new KeyValue[]{};

Map<System.Type, KeyValueBulk> keyMap = new Map<System.Type, KeyValueBulk>();
keyMap.put(Account.class, new KeyValueBulk(1, kvsA));
keyMap.put(Contact.class, new KeyValueBulk(5, kvsC));

TriggerController.rapidProcessing = new Map<System.Type, Boolean>{ Account.class => true, Contact.class => true};

//now rapidProcessing has been turned on for both objects the code in the triggers will be bypassed. You will need to build into your triggers the Trigger Control Framework:

TestDataComplexData dataCl = new TestDataComplexData ();

Ok for the above example for triggers to be bypassed we need to first create 2 Hierarchical custom settings:

            This custom settings needs to have the following fields:
Field Name
Data Type

            This custom settings needs to have the following fields:

Field Name
Data Type

            For each additional trigger you create you will need to create an additional             field in this custom setting for that trigger and you will need to add a new else if {} statement to the globalTriggerControlSetting() function in the       TriggerController class. An example of this will be shown next for the        Account and Contact

The 2 custom settings above can be used to bypass the triggers typically when either you are making a deployment to Production or if you are performing a data migration. They will allow you to disable individual or all triggers per person, per Profile or the entire system.

In the TriggerController class we created a number of variables to bypass the Account trigger, now create a similar set of variables for the Contact trigger. We also need to add 2 functions into the class globalTriggerControlSetting() and globalTriggerPerObjectControlSetting():

            //Contact - Only for testing to check if the code ran or not
            public static boolean Contact_Update_Succeeded = false;
            public static boolean Contact_Insert_Succeeded = false;
            public static boolean Contact_Delete_Succeeded = false;
            public static boolean Contact_UnDelete_Succeeded = false;

            //Contact - Disable / Enable parts of trigger
            public static boolean Contact_DisableAllTypes = false;
            public static boolean Contact_DisableInsert = false;
            public static boolean Contact_DisableUpdate = false;
            public static boolean Contact_DisableDelete = false;
            public static boolean Contact_DisableUnDelete = false;

public static boolean globalTriggerControlSetting(){
            return (((Triggers_Off__c.getOrgDefaults() != null) ? Triggers_Off__c.getOrgDefaults().value__c : false) || Triggers_Off__c.getInstance(UserInfo.getUserId()).value__c  || Triggers_Off__c.getInstance(UserInfo.getProfileId()).value__c) ;

public static boolean globalTriggerPerObjectControlSetting(String obj){
            if (obj == 'Account__c') return (((Trigger_Per_Object__c.getOrgDefaults() != null) ? (boolean)Trigger_Per_Object__c.getOrgDefaults().Account__c  : false) || (boolean)Trigger_Per_Object__c.getInstance(UserInfo.getUserId()).Account__c || (boolean)Trigger_Per_Object__c.getInstance(UserInfo.getProfileId()).Account__c) ;
            else if (obj == 'Contact__c') return (((Trigger_Per_Object__c.getOrgDefaults() != null) ? (boolean)Trigger_Per_Object__c.getOrgDefaults().Contact__c  : false) || (boolean)Trigger_Per_Object__c.getInstance(UserInfo.getUserId()).Contact__c || (boolean)Trigger_Per_Object__c.getInstance(UserInfo.getProfileId()).Contact__c) ;
            else return false;

The Disable variables eg: Contact_DisableAllTypes allows you to disable all of a trigger or individual parts of a trigger, commonly will be used within the body of the code including unit tests. We could have used the custom settings but that would involve using DMLs to turn the triggers on and off.

In the next blog we will create the code for the trigger.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.