You need to sign in to do that
Don't have an account?
Robert Davis 1
Test Class for Batch Process
I have a batch class that I have tested in a Sandbox with 10,000 records and it appears to be functioning as it should. My issue now is I can not seem to figure out the Test Class.
What basically happens is we have Sales Agents that are created as part of a custom Object. I go to the Account that these Sale Agents records are related to and create Accounts for each one and match the original Sales Agent record to the new Account.
I store the id for the Account in a Custom Setting.
The Batch Process:
Batch Schedule:
Robert
What basically happens is we have Sales Agents that are created as part of a custom Object. I go to the Account that these Sale Agents records are related to and create Accounts for each one and match the original Sales Agent record to the new Account.
I store the id for the Account in a Custom Setting.
The Batch Process:
global class CreateAccountsNewlyCreatedDSS implements Database.Batchable<sObject>, Database.Stateful { public disc2__c disc2 = disc2__c.getValues('DSS Agent Codes Account ID'); global ID AcctID = disc2.DSS_AccountID__c; // instance member to retain state across transactions global Integer recordsProcessed = 0; global Database.QueryLocator start(Database.BatchableContext bc) { return Database.getQueryLocator( 'SELECT id ,' + 'ssn__c,' + 'agent__c,' + 'ag_first_name__c,' + 'ag_last_name__c,' + 'agent_name__c ' + 'FROM agent_code__c ' + 'WHERE agent__c =: AcctID' ); } global void execute(Database.BatchableContext bc, List<Agent_Code__c> scope) { // process each batch of records map<string, account> ma = new map<string, account>(); for (agent_code__c ac: scope) { account a = new account(); a.AG_First_Name__c = ac.ag_first_name__c; a.AG_Last_Name__c = ac.ag_last_name__c; a.Name = ac.Agent_Name__c; a.SSN__c = ac.ssn__c; ma.put(a.SSN__c, a); recordsProcessed = recordsProcessed + 1; } Database.UpsertResult[] upsAgtCode = Database.upsert(ma.values(),account.fields.ssn__c, false); for(agent_code__c ac1: scope) { ac1.agent__c=ma.get(ac1.ssn__c).id; } database.update(scope, false); } global void finish(Database.BatchableContext bc){ System.debug(recordsProcessed + ' records processed. Shazam!'); List<Agent_Code__c> AgtCde = [SELECT id, Agent__c, Name FROM Agent_Code__c WHERE Agent__c =: AcctID]; AsyncApexJob job = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id = :bc.getJobId()]; // call some utility to send email List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>(); for(User usr: [SELECT id, email FROM User WHERE Profile.Name = 'System Administrator']) { System.debug('User Array of the System Administrators '+ usr); Messaging.SingleEmailMessage mail2 = new Messaging.SingleEmailMessage(); List<String> sendTo = new List<String>(); sendTo.add(usr.Email); mail2.setToAddresses(sendTo); List<String> ccTo = new List<String>(); ccTo.add('robert.d@XXX.com'); mail2.setCcAddresses(ccTo); mail2.setSubject('Apex Batched Job - Move Contacts from Distribution Supply Source Account'); string body = 'The Apex Batch Job named \'CreateAccountsNewlyCreatedDSS.apxc\' moves agent codes '; body += 'from the DSS Account and creates them as their own accounts. This process runs daily '; body += 'and was once a manual process. '; body += 'Below are the specifics of this batch job : <br/><br/>'; body += 'Apex Job '+ job + '<br/><br/>'; if(AgtCde.size() > 0) { body += 'List of Agent Codes that were not moved and need to be investigated : <br/><br/> '; for(Agent_Code__c ac: AgtCde) { body += ' This record id <b>' + ac.Id + '</b> was not moved. <br/>'; body += ' This is the Agent Code that did not process <b>'+ ac.Name+'</b>.<br/><br/>'; } } else { body += '<b>No Records were left behind</br>. All records matched the requirements to create Accounts. '; } body += '<br/><br/>For more information on this process and how it should work go to the Admin Routines in '; body += 'New Parts Salesforce Org and go to #NewAgentCodes:MovefromTheNewAgentCodeAccountBucket .'; mail2.setHtmlBody(body); mails.add(mail2); } Messaging.sendEmail(mails); } }
Batch Schedule:
global class MoveAgentCodesBatchScheduler implements Schedulable { global void execute(SchedulableContext sc) { // Implement any logic to be scheduled // We now call the batch class to be scheduled CreateAccountsNewlyCreatedDSS b = new CreateAccountsNewlyCreatedDSS(); //Parameters of ExecuteBatch(context,BatchSize) database.executebatch(b,2000); } }Test Class that not only seems to have to many DML statements but also de-reference a null object.
@isTest public class CreateAccountsNewlyCreatedDSS_Batch_Test { @testSetup static void setup() { Account acct = New Account(Name= 'Test Account' ); insert acct; List<Agent_Code__c> lstAgtCd = new List<Agent_Code__c>(); for(Integer i=0; i<20; i++) { lstAgtCd.add(new Agent_Code__c(Agent__c = acct.id, Name = 'AgentTestCode'+i, ag_first_name__c = 'AgentFirstTestName'+i, ag_last_name__c = 'AgentLastTestName'+i, ssn__c = i+'2341' )); } insert lstAgtCd; } static testmethod void test() { Test.startTest(); CreateAccountsNewlyCreatedDSS testBatch = new CreateAccountsNewlyCreatedDSS(); Id batchprocessId = Database.executeBatch(testBatch,10000); Test.stopTest(); } }Your help is appreciated. Thank you in advance for any insight.
Robert
Your problem is the custom settings at the beginning that are not resolved.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_custom_settings.htm
You can try this:
All Answers
Your problem is the custom settings at the beginning that are not resolved.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_custom_settings.htm
You can try this:
Thank you, so very much.
Robert
The code now passes test but it does not seem to be creating the agent codes and attaching them to the account for the process to loop through and act on. Any thoughts on how this might be solved?
Robert
It seems that disc2.DSS_AccountID__c is still null (?).
What is the result?
No longer am I getting I am getting 61% Code Coverage but the test code is not accessing the following area of code and not processing any records to move:
The code is skipping executing this part of the batch class.
Thanks
Robert
If that fails, that means that disc21.DSS_AccountID__c is null and that is the problem.
If the request returns no result for the query locator then the batch could not be launched and the request returns nothing if disc21.DSS_AccountID__c is not correct (null value)(tested with the lines above).
List<Agent_Code__c> scope is empty if the query locator returns nothing because the global ID AcctID = disc2.DSS_AccountID__c; is null probably.
assert(condition, msg): Asserts that the specified condition is true. If it is not, a fatal error is returned that causes code execution to halt.
Logically, AcctID1 is null (bad) and so that failed at the Assert but you see that the Debug returned an AccountID (?)
The initialisation of DSS_AccountID__c in the setup could be wrong finally.
DSS_AccountID__c exists now (no error of de-reference null) but with a wrong value.
If you remove the assert or change System.assertEquals(null, AcctID1); that is alway ok ?
or System.assertNotEquals(null, AcctID1);
If you see a correct AccountID for the request, that should work.
You can try to move all the setup code just before your Test.startTest();
If AcctID is not null, that should work because there are many records into agent__c ( insert lstAgtCd; )
Verify with this assert : System.assertNotEquals( 0 , [select count() from agent_code__c where agent__c = : AcctID1);
Thanks for all the help. I wanted to follow up and let you know what the issue is / was. I created the Account ID, I then created the Custom Setting, I then assigned a variable to the custom setting field, but never did a Update.
So the following line of code fixed all the issues:
Thank you for your time and help. Ohana.
Robert