function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Nishant Shah 9Nishant Shah 9 

Urgent - test class for batch apex

Hello Experts,

Below is the batch class that I've written, however, the functionality is all the cases should be cloned on anniversary (date field) of an account but this is not working. Experts, please help me to write test class for the below batch as i'm beginner and need it urgent
 
public class CaseCloneOnAccountAnniversary implements Database.Batchable<SObject>,Schedulable
{
    public static final String BATCH_JOB_TITLE = 'My Batch Job';
    String errors = '';
    
    integer todayday = date.today().day();
    Integer currentmonth = date.today().month();

    public Map<Id, String> errorMap = new Map<Id, String>();
    public Map<Id,Case> IdToSObjectMap = new Map<Id, Case>();
    
    public Database.QueryLocator start(Database.BatchableContext bc)
    {
       return Database.getQueryLocator('SELECT Anniversary__c,Id from Account WHERE Anniversary__c = DAY_IN_MONTH(Anniversary__c) =:todayday AND CALENDAR_MONTH(Anniversary__c ) =: currentmonth') ;
    }
        
    
    public void execute(Database.BatchableContext bc, List<SObject> scope)
    {
        if(scope.isEmpty()) return;
        //List<Account> accts = (List<Account>) scope;
        // Lis<Account> acctsList = new List<Account>();
        List<Case> caseToCreateList = new List<Case>();
        
        
       // for( Account aAccount : (Account)scope )
       for(Account aAccount:[Select Id,(Select Id from cases order by CreatedDate limit 1) from account where Id IN : scope]) //Add all field in case query which you want to copy
        {
            if(aAccount.cases.size() > 0)
            {
                Case objCase = new Case();
                objCase  = aAccount.cases[0].clone(false, true);

                // collecting the Cases to create
                caseToCreateList.add(ObjCase);
            }
            
       }
        try
        {
           if(!caseToCreateList.isEmpty()) 
           { 
                        
             Database.SaveResult[] srList = Database.insert(caseToCreateList, false);
             Integer index = 0;
             system.debug('---srList  first'+ srList );
             
             for(Database.SaveResult result : srList )
             {
                if(!result.isSuccess())
                {
                    String errMsg = result.getErrors()[0].getMessage();
                    errorMap.put(caseToCreateList[index].Id, errMsg);
                    IdToSObjectMap.put(caseToCreateList[index].Id, caseToCreateList[index]);
                } // End Inner If
                index++;
              } // End for
            
            } // End Outer If
        } // End try
        catch( Exception ex )
        {
                this.errors += ex.getMessage();
        }
     }

    public void finish(Database.BatchableContext context)
    {
       //Send an email to the User after your batch completes 
       if(!errorMap.isEmpty()){
       AsyncApexJob a = [SELECT id,ApexClassId,JobItemsProcessed,TotalJobItems,NumberOfErrors, CreatedBy.Email FROM AsyncApexJob WHERE id = :context.getJobId()];
       
       String body = 'Your batch job '
             + 'CaseCloneOnAccountAnniversary'
             + 'has finished. \n' 
             + 'There were '
             + errorMap.size()
             + ' errors. Please find the error list attached to the mail.';
             
       // Creating the CSV file
        String finalstr = 'Id, Subject, Error \n';
        String subject = 'CaseCloneOnAccountAnniversary- Apex Batch Error List';
        String attName = 'CaseCloneOnAccountAnniversary Errors.csv';      
        
        for(Id id  : errorMap.keySet()){
                string err = errorMap.get(id);
                Case objCase = (Case) IdToSObjectMap.get(Id);
                String recordString = '"'+id+'","'+ objCase.Subject +'","'+ err +'"\n';
                finalstr = finalstr +recordString;
            } 
            
            // Define the email
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); 
 
            // Create the email attachment    
            Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
            efa.setFileName(attName);
            efa.setBody(Blob.valueOf(finalstr));
 
            // Sets the paramaters of the email
            email.setSubject( subject );
            email.setToAddresses( new String[] {'abc@gmail.com'} );
            email.setPlainTextBody( body );
            email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
 
            // Sends the email
            Messaging.SendEmailResult [] r = 
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});   
       
      }       
    }

    public void execute(SchedulableContext sc)
    {
        CaseCloneOnAccountAnniversary scheduleBatch= new CaseCloneOnAccountAnniversary();
        Database.executeBatch(scheduleBatch);
    }

        
   }

 
ShikhaJainShikhaJain
Hi Nishant,

The basic steps to write your test class would be :
1) Create test data that will satisfy the condition
2) Within the Test.StartTest() and Test.StopTest() invoke the batch class. When a test class is run, the batch will be invoked immediately after the Test.StopTest().
3) After the Test.StopTest() Method, query and verify if the data was created or no.

For more details, you can refer to the following link: https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_2.htm

Regards,
Shikha
Nishant Shah 9Nishant Shah 9
Yes, have been reading the docs on this. But , this is something which is the first time and need it urgently. Could you please help code to me for the test class.
 
ShikhaJainShikhaJain
Can you please paste the code for the test class that you have tried/written so far.
Nishant Shah 9Nishant Shah 9
This is what I tried but think its wrong
 
@isTest 
public class CaseCloneOnAccountAnniversaryTest
{
    static testMethod void testMethod1() 
    {
      
	  // create an account
		Account MyAccount = new Account(Name='Test');
		insert MyAccount;

	 // Create a case on the test account
		date myDate = date.today();
		Account MyCase = new Account(Name='Test');
		MyCase.AccountId = MyAccount.Id;	
		insert MyCase;
		
	    Test.startTest();
		CaseCloneOnAccountAnniversary casebatch = new CaseCloneOnAccountAnniversary(MyCase);
		Database.executeBatch(casebatch );
        Test.stopTest();
	  
	    
	  
	    
	  
	  
    }
}

 
ShikhaJainShikhaJain
Can you please try this:

@isTest 
public class CaseCloneOnAccountAnniversaryTest
{
    static testMethod void testMethod1() 
    {
      
        //create an account
        date myDate = date.today();
        Account MyAccount = new Account(Name='Test',Anniversary__c = myDate);
        insert MyAccount;

        //Create a case on the test account
        Case MyCase = new Case(Subject='TestCase',AccountId=MyAccount.id);
        insert MyCase;
        
        Test.startTest();
            CaseCloneOnAccountAnniversary casebatch = new CaseCloneOnAccountAnniversary(MyCase);
            Database.executeBatch(casebatch);
        Test.stopTest();
        
        //Kindly add Assert statements to verify that the batch executed correctly
   }
}