In my last blog http://stevefouracre.blogspot.co.uk/2015/06/intro-to-unit-test-data-creation.html I gave examples of how the framework
can be used. I also introduced rapidProcessing. Now we will expand the
framework making use of rapidProcessing.
Reminder:
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 ();
dataCl.insertAccountAndContacts(keyMap);
|
Ok for the above example for triggers to be bypassed we need
to first create 2 Hierarchical custom settings:
Triggers_Off__c
This custom
settings needs to have the following fields:
Field Name
|
Data Type
|
value
|
Boolean
|
Trigger_Per_Object__c
This custom
settings needs to have the following fields:
Field Name
|
Data Type
|
Account
|
Boolean
|
Contact
|
Boolean
|
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){
Trigger_Per_Object__c.getInstance(UserInfo.getProfileId()));
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.