Hello and thank you in advance. I'm having a heck of a time testing my class enough to be able to implement into production. I've created a batchable class that I intend to execute via Execute Anonymous.
The problem I'm seeing is that a) I can't implement the batchable class until 75% of its code is covered b) I've created a test class that uses Database.executeBatch() to run the batch (and provides coverage for the batchable class). However, this is all fine and dandy in a sandbox where I can have the batchable class employed, but in production I receive an error as the BatchMerge class doesn't exists yet (due to not being able to deploy due to lack of code coverage).
Here is my BatchMerge class:
public class BatchMerge implements Database.Batchable<sObject>
{
public Database.QueryLocator start(Database.BatchableContext context)
{
return Database.getQueryLocator(
[SELECT
Contact_to_Merge_Into__c,
Contact__c,
Merge_missing_data__c,
// contact data
Contact_to_Merge_Into__r.Phone,
Contact__r.Phone,
Contact_to_Merge_Into__r.Function__c,
Contact__r.Function__c,
Contact_to_Merge_Into__r.Title,
Contact__r.Title,
Contact_to_Merge_Into__r.MobilePhone,
Contact__r.MobilePhone,
Contact_to_Merge_Into__r.How_Contacted__c,
Contact__r.How_Contacted__c,
Contact_to_Merge_Into__r.OtherPhone,
Contact__r.OtherPhone,
Contact_to_Merge_Into__r.LeadSource,
Contact__r.LeadSource,
Contact_to_Merge_Into__r.Fax,
Contact__r.Fax,
Contact_to_Merge_Into__r.Lead_Source_Detail__c,
Contact__r.Lead_Source_Detail__c,
Contact_to_Merge_Into__r.DoNotCall,
Contact__r.DoNotCall,
Contact_to_Merge_Into__r.HasOptedOutOfEmail,
Contact__r.HasOptedOutOfEmail,
Contact_to_Merge_Into__r.Mail_Opt_Out__c,
Contact__r.Mail_Opt_Out__c,
Contact_to_Merge_Into__r.Include_In_Email_Distribution__c,
Contact__r.Include_In_Email_Distribution__c
FROM Contact_Merge_Record__c
WHERE Merge_Status__c != 'Merge Completed' ]
);
}
public void execute(Database.BatchableContext context, Contact_Merge_Record__c[] records)
{
for(Contact_Merge_Record__c record: records)
{
String mergedFrom = null;
record.Last_Merge_Attempt__c = system.now();
update record;
/// Update Detail Vars
try
{
// forces contact field changes to be tracked.
mergedFrom = record.Contact__c;
record.Contact__c = record.Contact__c;
update record;
// merge/delete
Database.merge(new Contact(Id=record.Contact_to_Merge_Into__c), record.Contact__c);
// update extra data based on merge missing data flag
if(record.Merge_missing_data__c == true)//record.Merge_missing_data__c == true)
{
// Capture updates to be made
List<Contact_Merge_Record_Update__c> RecordUpdates = new List<Contact_Merge_Record_Update__c>();
String Merged_Contact_ID = record.Contact__r.ID; // doesn't change
ID Contact_Merge_Record = record.ID; // doesn't change
String Updated_field = null;
String Master_Record_original_value = null;
String Updated_Value = null;
String Merge_Contact_original_value = null;
update record.Contact_to_Merge_Into__r; // wait to make updates until update detail records are made (validate?)
insert RecordUpdates;// insert updates
// update record.Contact_to_Merge_Into__r; // from above
} // end if
//update record to point to master record;
record.Contact__c = record.Contact_to_Merge_Into__c;
record.Merge_Status__c = 'Merge Completed';
record.Merge_Date__c = system.now();
record.Contact_Merged__c = mergedFrom;
record.Merge_Details__c = null;
update record;
} // end try
catch(Exception e)
{
if(record.Contact_to_Merge_Into__c == mergedFrom)
{
record.Merge_Details__c = 'Cannot merge the same record into the same record.';
}
else
{
record.Merge_Details__c = e.getMessage() + ', due to: ' + e.getCause();
}
record.Merge_Status__c = 'Merge failed (See Details)';
update record;
}
} // end loop
}
public void finish(Database.BatchableContext context)
{
}
}
Here is my test class:
@IsTest(SeeAllData=true)
public with sharing class BatchMergeTestClass
{
@IsTest(SeeAllData=true)
static void testUpdate()
{
Database.executeBatch(new BatchMerge(), 10);
}
}
Here is my UPDATED test class:
@IsTest
public with sharing class BatchMergeTestClass
{
@IsTest
static void testUpdate()
{
List<Account> Accounts = new List<Account>();
List<Contact> Contacts = new List<Contact>();
List<Contact_Merge_Record__c> ContactMergeRecords = new List<Contact_Merge_Record__c>();
Accounts.add(new Account(Name = 'Test Account'));
Contacts.add(new Contact(FirstName = 'Test First 1', LastName = 'Test Last 1'));
Contacts.add(new Contact(FirstName = 'Test First 2', LastName = 'Test Last 2'));
insert Accounts;
insert Contacts;
Contact Contact1 = new Contact(FirstName = 'Test First 1', LastName = 'Test Last 1');
Contact Contact2 = new Contact(FirstName = 'Test First 2', LastName = 'Test Last 2');
Contacts.add(Contact1);
Contacts.add(Contact2);
insert Contacts;
Contact_Merge_Record__c ContactMergeRecord = new Contact_Merge_Record__c();
ContactMergeRecord.Contact_to_Merge_Into__c = Contact1.Id;
ContactMergeRecord.Contact__c = Contact2.Id;
ContactMergeRecords.add(ContactMergeRecord);
insert ContactMergeRecords;
BatchMerge bm = new BatchMerge();
Test.startTest();
Database.executeBatch(bm, 10);
ID batchprocessid = Database.executeBatch(bm);
Test.stopTest();
}
}
Database.executeBatch()
. This class should be creating all the data you need to test the corresponding batch class. Be sure you aren't using@IsTest(SeeAllData=true)
.