Apex Unit Testing and Anonymous scripting – The Generic…
Been writing a cool Utility method which allows me to create my testing data in much easier manner taking under consideration Users that create independently Fields with the required checkbox on => which cause all Testing class that is trying to insert/update this sObject to fail.
I was trying to create manually few sample records and also encountered issues, as I have multiple required fields to populated that I was not aware of – so instead of start investigating and naming field by field I thought will be better to have my code do it for me.
This also can be used as Anonymous script to insert any sObject with a short notation.
- Example for invoking generic method with one sObject
To run this Method simply invoke it :
public static void createAccounts(Integer numAccounts ) { List<Account> accs = getSObjectWithAllRequiredFields('Account',numAccounts); insert accs; }
This can be placed as standalone Class such as DataSampler or an annotated @IsTest Class, also can be just copy pasted as anonymous script.
/****************** @methodName : getSObjectWithAllRequiredFields @description : Generic Method that Will dynamically get sObject list with all reuiquired ad editable fields populated. @params : Accepting an SObject API Name and the number of records to create @return : List<sObject> to perform Insert DML *****************/ public static List<sObject> getSObjectWithAllRequiredFields( String objectName, Integer numOfRecords ) { List <Map<String,Object>> allFieldsList = new List <Map<String,Object>> (); Schema.SObjectType mySObj = Schema.getGlobalDescribe().get(objectName); List<SObject> sobjectList = new List<SObject> (); Map<String,Schema.SObjectField> mapFields = mySObj.getDescribe().fields.getMap(); // Validate which fields are Required or Editable fields for this sObject for(String fieldName : mapFields.keyset()){ Schema.DescribeFieldResult fieldDescribe = mapFields.get(fieldName).getDescribe(); if(!fieldDescribe.isNillable() && // is required fieldDescribe.isCreateable() && !fieldDescribe.isDefaultedOnCreate() && !fieldDescribe.isCalculated() && //formula !fieldDescribe.isAutoNumber() && fieldDescribe.isUpdateable()){ Map<String,Object> fieldMap = new Map<String,Object>{ 'FieldAPIName__c' => fieldDescribe.getName(), 'isRequired' => !fieldDescribe.isNillable(), 'FieldType' => fieldDescribe.getType(), 'isUnique' => fieldDescribe.isUnique(), 'isExternalID' => fieldDescribe.isExternalID() }; switch on fieldDescribe.getType(){ when String,TextArea{ fieldMap.put('Length',fieldDescribe.getLength()); //maximum size of the field } when Picklist,MultiPicklist{ fieldMap.put('PicklistValues',fieldDescribe.getPicklistValues()); fieldMap.put('isDependentPicklist',fieldDescribe.isDependentPicklist()); } when Double ,Percent, Integer,Currency{ fieldMap.put('Length',fieldDescribe.getPrecision() - fieldDescribe.getScale()); //actual length fieldMap.put('Precision',fieldDescribe.getPrecision()); //maximum number of digits that can be stored fieldMap.put('Digits', fieldDescribe.getDigits()); //Returns the maximum number of digits specified fieldMap.put('Scale', fieldDescribe.getScale()); // Decimal Places => number of digits to the right of the decimal point } when Reference { fieldMap.put('ReferenceTargetField',fieldDescribe.getReferenceTargetField()); fieldMap.put('ReferenceTo',fieldDescribe.getReferenceTo()); //sObjectName } } allFieldsList.add(fieldMap); } } // Create sObject with all fields collected for(Integer i =0 ; i<numOfRecords; i++) { SObject myNewSObject = mySObj.newSObject(); for(Map<String,Object> keyMap: allFieldsList) { //System.debug('@@@ Required Field details :' + JSON.serialize(keyMap)); if(!(Boolean)keyMap.get('isUnique') && !(Boolean)keyMap.get('isExternalID') ){ switch on (Schema.DisplayType)keyMap.get('FieldType'){ when Integer, Currency, Percent{ String sampleNumber = '1234567890' +i; sampleNumber = sampleNumber.right((Integer)keyMap.get('Length')); Integer myInt = math.round(Integer.valueOf(sampleNumber)); myNewSObject.put((String)keyMap.get('FieldAPIName__c'),myInt); } when Double{ myNewSObject.put((String)keyMap.get('FieldAPIName__c'), 1.1); } when String, TextArea { String sampleText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua' + i; myNewSObject.put((String)keyMap.get('FieldAPIName__c'), sampleText.right((Integer)keyMap.get('Length'))); } when Phone { myNewSObject.put((String)keyMap.get('FieldAPIName__c'), '9723786 '+i); } when Email { myNewSObject.put((String)keyMap.get('FieldAPIName__c'), 'test'+i+'@email.com'); } when Picklist,MultiPicklist { List<Schema.PicklistEntry>picklist = (List<Schema.PicklistEntry>)keyMap.get('PicklistValues'); myNewSObject.put((String)keyMap.get('FieldAPIName__c'), picklist[0].value); //use first option value as default } when Date { myNewSObject.put((String)keyMap.get('FieldAPIName__c'), Date.today()); } when DateTime { myNewSObject.put((String)keyMap.get('FieldAPIName__c'), DateTime.now()); } when Time { myNewSObject.put((String)keyMap.get('FieldAPIName__c'), Time.newInstance(1, 2, 3, 4)); } when URL { myNewSObject.put((String)keyMap.get('FieldAPIName__c'), 'www.test.com'); } when Reference { System.debug('Populate required lookups on your outer method => ReferenceTargetField ' + keyMap.get('ReferenceTargetField') + ' ReferenceTo ' + keyMap.get('ReferenceTo')); } } //end switch } else { // support for External Unique key } } sobjectList.add(myNewSObject); } return sobjectList; }