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
krishna3krishna3 

Batch apex test class code coverage

Hi everyone,

i have complete the test cass for my Batch apex class. when i was test that code in Developer and Test sandbox its covered 100%. when i deploy that code to QA its show only 27% without any errors.

 

when i check that code DEBUG LOG i got this error....

 

|EXCEPTION_THROWN|[EXTERNAL]|System.UnexpectedException: No more than one executeBatch can be called from within a testmethod. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation.
12:18:21.557|FATAL_ERROR|System.UnexpectedException: No more than one executeBatch can be called from within a testmethod. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation.

 

here is the Batch apex and corresponding test classes.

 

Apex Class:

 

global class ParentContactDefaultDeliverToUpdate implements Database.Batchable<sObject>,Schedulable{

  global String Query;
   
    global ParentContactDefaultDeliverToUpdate(){
     
      Query = 'SELECT Id, otc_contact_id__c, Default_Deliver_To_OTC_Contact_Id__c, Parent_OTC_Contact_Id__c, Needs_Parent_OTC_Contact_Update__c FROM OTC_Contact__c WHERE Needs_Parent_OTC_Contact_Update__C=TRUE';
    }

    global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator(query);
    }
     global void execute(SchedulableContext SC){
        ParentContactDefaultDeliverToUpdate obj = new ParentContactDefaultDeliverToUpdate();
        database.executebatch(obj);
        
    }

    global void execute(Database.BatchableContext BC, List<sObject> scope){
    
       Set<String> parentOtcExtIds = new Set<String>(); 
      // Set<String> ddToOtcExtIds = new Set<String>();       
       
       for(sObject s : scope){
           OTC_Contact__c otcCon = (OTC_Contact__c)s;
           if((otcCon.Parent_OTC_Contact_Id__c != NULL)
               || (otcCon.Default_Deliver_To_OTC_Contact_Id__c != NULL) ){
               parentOtcExtIds.add(otcCon.Parent_OTC_Contact_Id__c);
               parentOtcExtIds.add(otcCon.Default_Deliver_To_OTC_Contact_Id__C);
           }
          /* if(otcCon.Default_Deliver_To_OTC_Contact_Id__c != NULL && otcCon.Default_Deliver_To__c == NULL){
               ddToOtcExtIds.add(otcCon.Default_Deliver_To_OTC_Contact_Id__c);
           }*/
       }
       
       List<OTC_Contact__c> OtcContacts = [Select id,Otc_Contact_Id__c from OTC_Contact__c where Otc_Contact_Id__c IN :parentOtcExtIds];
       Map<String,Id> otcContactMap = new Map<String,Id>();
       for(OTC_Contact__c otc : OtcContacts){
           otcContactMap.put(otc.Otc_Contact_Id__c,otc.Id);
       }
       
       for(sObject s : scope){
           OTC_Contact__c otcCon = (OTC_Contact__c)s;
            if(otcCon.Parent_OTC_Contact_Id__c != NULL && otcContactMap.containsKey(otcCon.Parent_OTC_Contact_Id__c)){
                otcCon.Parent_OTC_Contact__c = otcContactMap.get(otcCon.Parent_OTC_Contact_Id__c);
            }
            if(otcCon.Default_Deliver_To_OTC_Contact_Id__c != NULL && otcContactMap.containsKey(otcCon.Default_Deliver_To_OTC_Contact_Id__c )){
                otcCon.Default_Deliver_To__c = otcContactMap.get(otcCon.Default_Deliver_To_OTC_Contact_Id__c );            
            }
          otcCon.Needs_Parent_OTC_Contact_Update__c = FALSE;
          otcCon.Parent_OTC_Contacts_Updated__c = TRUE;  
       }
       update scope;
       
    }
 
    global void finish(Database.BatchableContext BC){
    }
}

 

TEST CLASS:


@isTest

Private class ParentContactDefaultDeliverToUpdate_Test
{
  static testMethod void Testclass(){  

  
   Account acc = new Account(Name = 'Test Name',phone = '53453455435', Customer_Segment__c = 'Bookstore',Account_Status__c = 'Active',
                                    INTG_Physical_Address_Line_1__c = 'Street', 
                                    INTG_Physical_Address_Line_2__c = 'Apt 3',
                                    INTG_Physical_City__c = 'Tarrytown',
                                    INTG_Physical_State_Province_Region__c = 'New York',
                                    INTG_Physical_Country__c = 'USA',
                                   INTG_Physical_Postal_Code__c = '94538'); 
    insert acc; 
    
     Unit__c ut1 = New Unit__c(Name = ' test', Account__c = acc.id);
    
    insert ut1; 
    
    Contact con = new Contact(FirstName = 'Test Name', accountId = acc.id, LastName = 'Test', Phone = '5345345545', Contact_Status__c = 'Active',
                                    INTG_Physical_Address_Line_1__c = 'Street', 
                                    INTG_Physical_Address_Line_2__c = 'Apt 3',
                                    INTG_Physical_City__c = 'Tarrytown',
                                    INTG_Physical_State_Province_Region__c = 'New York',
                                    INTG_Physical_Country__c = 'USA',
                                   INTG_Physical_Postal_Code__c = '94538');     
    insert con;

    OTC_Contact__c otc1 = new OTC_Contact__c(name= 'test', Last_Name__c = 'test', Contact__c = con.id, OTC_Contact_Type__c='AR', 
                                             Otc_Contact_Id__c = '123ARUNISON');
    insert otc1;
    
    OTC_Contact__c otc2 = new OTC_Contact__c(name= 'test', Last_Name__c = 'test', Contact__c = con.id, otc_contact_type__c='SOLDTO',
                                             Otc_Contact_Id__c = '12345SOLDTOUNISON', parent_otc_contact_id__c='123ARUNISON', parent_otc_contact__c=otc1.id, needs_parent_otc_contact_update__c=TRUE);
    insert otc2;
    
    OTC_Contact__c otc3 = new OTC_Contact__c(name='test3', Last_Name__c='test contact', Contact__c= con.id, otc_Contact_type__c='DELIVERTO',
                                               otc_contact_id__c='321DELIVERTOUNISON');
    insert otc3;                                           
    
    OTC_Contact__c otc4 = new OTC_Contact__c (Name = 'Test3', Last_Name__c = 'test3', contact__c = con.id,
                                              Otc_Contact_Id__c='1234SHIPTOUNISON', otc_contact_type__c='SHIPTO', default_deliver_to_otc_contact_id__c='321DELIVERTOUNISON', 
                                              default_deliver_to__c=otc3.id, needs_parent_otc_contact_update__c=TRUE);
    insert otc4;
    
      
    Test.StartTest();  
    
// Schedule the job
        ParentContactDefaultDeliverToUpdate obj1 = new ParentContactDefaultDeliverToUpdate();
      
   //  obj1.query='SELECT Id, otc_contact_id__c, Default_Deliver_To_OTC_Contact_Id__c, Parent_OTC_Contact_Id__c, Needs_Parent_OTC_Contact_Update__C FROM OTC_Contact__c WHERE Needs_Parent_OTC_Contact_Update__C=\' ' + TRUE + '\'  LIMIT=200';
    ID batchprocessid = Database.executeBatch(obj1);
   // OrderTransactionUpdate obj = new OrderTransactionUpdate();
  //  database.executebatch(obj);
  ParentContactDefaultDeliverToUpdate p = new ParentContactDefaultDeliverToUpdate();        
   String sch = '0 0 8 13 2 ?';        
  system.schedule('Schedule Test', sch, p);
  
 Test.stopTest();
       }

 }

 

can anyone help me out with this issue....ITS URGENT

 

thanks in advance....

 

Best Answer chosen by Admin (Salesforce Developers) 
krishna3krishna3

thanks for the reply..

 

here is the solution

 

Query = 'SELECT Id, otc_contact_id__c, Default_Deliver_To_OTC_Contact_Id__c, Parent_OTC_Contact_Id__c, Needs_Parent_OTC_Contact_Update__c FROM OTC_Contact__c WHERE Needs_Parent_OTC_Contact_Update__C=TRUE LIMIT 200';

 

All Answers

BritishBoyinDCBritishBoyinDC

The Query string you use isn't limited (it looks like the one in the script is commented out which has a limit) so I am guessing you have more than 200 rows in Live that match the criteria - in which case the batch will try and execute more than once...

 

 

I would suggest setting the query string after you create the object as part of the schedule object or however you initiate the batch e.g.

 

ParentContactDefaultDeliverToUpdate obj = new ParentContactDefaultDeliverToUpdate();

obj.query = 'Select...'

 

Then,  when you run the test script, you can include the limit 200 statement and any other filters you need when you test the batch to make sure the numbers are limited and that the test data is included in the execution (as of now, there is no way to ensure that happens)

Ankit AroraAnkit Arora

Not sure but have a gut feel that this will work :

 

 ID batchprocessid = Database.executeBatch(obj1 , 1);

 

Just give the batch size one once and try.

 

Thanks

Ankit Arora

Blog | Facebook | Blog Page

krishna3krishna3

thanks for the reply..

 

i tried both these scenarios..but it is still showing 27% only.

 

is there any other solution..

BritishBoyinDCBritishBoyinDC

Are you still getting an error? Is the batch just executing but not testing any of the logic?

 

Check test data you created is included in the 200 records returned by the SOQL...I would add some debug statements to confirm you records are being included and being processed as expected...

 

Typically, low coverage is due to the data being processed not triggering the if conditions, so the code is never tested

krishna3krishna3

thanks for the reply,

yes, the if conditions are not covered in the test coverage.

 

i am able to shcedule the job and batches are processing succesfully.

 

can you please help me out how to solve this issue.

BritishBoyinDCBritishBoyinDC

If all the records are linked to the same test contact, I would build the SOQL string to filter specifically for that contact in your test script...

 

e.g. 

 

 

Query = 'SELECT Id, otc_contact_id__c, Default_Deliver_To_OTC_Contact_Id__c, Parent_OTC_Contact_Id__c, Needs_Parent_OTC_Contact_Update__c FROM OTC_Contact__c WHERE Needs_Parent_OTC_Contact_Update__C=TRUE AND Contact__c = \' ' + con.Id + '\' ';

 

That way, your test records should be included in the batch, and assuming they trigger the IF conditions, it should work...

 

krishna3krishna3

thanks for the reply..

 

here is the solution

 

Query = 'SELECT Id, otc_contact_id__c, Default_Deliver_To_OTC_Contact_Id__c, Parent_OTC_Contact_Id__c, Needs_Parent_OTC_Contact_Update__c FROM OTC_Contact__c WHERE Needs_Parent_OTC_Contact_Update__C=TRUE LIMIT 200';

 

This was selected as the best answer
SatSSatS

 

Hi Krishna,

Can you help out for writing test class for below Batch Class. I never wrote any test class so your response is highly appreciable. Thanks in Advance

 

global class UpdateClientTickerClass implements Database.Batchable<sObject> {

   global Database.QueryLocator start(Database.BatchableContext BC){
      system.debug(':- Inside Start');

      //query = 'SELECT Id, DUNS_Number__c from Account WHERE ClientTickerFlag__c = true';
      return Database.getQueryLocator('SELECT Id, DUNS_Number__c from Account WHERE ClientTickerFlag__c = true');
   }
  
   global void execute(Database.BatchableContext BC, List<Account> scope)
   {
        system.debug(':- Execute Started');
        //List<Account> UpdatedAccounts = new List<Account>();
        List<Client_Ticker__c> NewClientTickers= new List<Client_Ticker__c>();
        List<Client_Ticker__c> DeleteClientTickers= new List<Client_Ticker__c>();
        List<Account> clientToUpdate = new List<Account>();
    for(Account S: Scope)
    {
      s.ClientTickerFlag__c = false;
      S.Tax_ID__c = NULL;
      system.debug(':- Inside Scope');
      system.debug(':- Processing Client: '+ S.Id);
     
      // Delete existing Client Tickers for the Accounts
      for(Client_Ticker__c OCT :[select Id From Client_Ticker__c where  Client__c =:s.id LIMIT 50000])
      {
        DeleteClientTickers.add(OCT);
        system.debug(':- Ticker added to delete: '+ S.Id + ' : ' + OCT.id);
      }
      system.debug(':- Done with ticker deletion for client: '+ s.id);
     
      if(S.DUNS_Number__c <> NULL && S.DUNS_Number__c <> '')
      {
       
        system.debug(':- DUNS not null for ' + S.Id);
       
        // Lookup and Add New Client Tickers       
        FEIN__c[] Ultimate_Parent = [select Global_Ultimate_Parent_DUNS_Number__c, Name From FEIN__c where  DUNS_Number__c  = :String.valueOf(S.DUNS_Number__c) Limit 1];
        Master_Ticker_List__c [] MTicker = [select Id, DUNS_Number__C, Ticker_Unique_Name__C From Master_Ticker_List__c where Ticker_Unique_Name__C like :S.DUNS_Number__c+'%' LIMIT 50000];
        system.debug(':- Master tickers found for Client: '+ S.id + ' : '+ MTicker.size());
        if(MTicker.size() > 0)
        {
          system.debug(':- Processing with CLient Duns number');
          for(Master_Ticker_List__c MTicker_Rec: MTicker)
          {
                      system.debug(':- Processing Master Ticker: ' + MTicker_rec.Id);
                      Client_Ticker__c CTicker_rec = new Client_Ticker__c(); 
                      CTicker_rec.Client__c = S.Id;
                      CTicker_rec.Master_Ticker_Number__c = MTicker_rec.ID;
                      NewClientTickers.add(CTicker_rec);                         
          }
        } else
        {
          system.debug(':- Processing with Ultimate Parent Duns number');
         
          system.debug(':- Size of Ultimate Parent: '+ Ultimate_Parent.size());         
          if(Ultimate_Parent.size() > 0)
          {
            system.debug(':- Duns Number of Ultimate Parent: '+ Ultimate_Parent[0].Global_Ultimate_Parent_DUNS_Number__c);
            MTicker = [select Id, DUNS_Number__C, Ticker_Unique_Name__C From Master_Ticker_List__c where Ticker_Unique_Name__C like :Ultimate_Parent[0].Global_Ultimate_Parent_DUNS_Number__c +'%' LIMIT 50000];           
            system.debug(':- Master tickers found for Ultimate Parent : '+ S.id + ' : '+ MTicker.size());
            for(Master_Ticker_List__c MTicker_Rec: MTicker)
            {
                        system.debug(':- Processing Master Ticker from ultimate parent: ' + MTicker_rec.Id);
                        Client_Ticker__c CTicker_rec = new Client_Ticker__c(); 
                        CTicker_rec.Client__c = S.Id;
                        CTicker_rec.Master_Ticker_Number__c = MTicker_rec.ID;
                        NewClientTickers.add(CTicker_rec);
            }           
          }

        }
       
        //Update FEIN for client
       
          if(Ultimate_Parent.size() > 0)
          {
          s.Tax_ID__c = Ultimate_Parent[0].Name;
          }
        //FEIN update done 
      }
    system.debug(':- Finished processing Client: ' + s.Id);
   
      clientToUpdate.add(s);
         
    }// End of for loop 
         
    if(NewClientTickers.size() > 0)
    {
      insert NewClientTickers;
    }
    if(DeleteClientTickers.size() > 0)
    {
      delete DeleteClientTickers;
    }
    if(clientToUpdate.size() > 0)
    {
      update clientToUpdate;
    }
   }
  
  
   global void finish(Database.BatchableContext BC){
      
       AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id = :BC.getJobId()];
                         
       // Send an email to the Apex job's submitter
       Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
       String[] toAddresses = new String[] {a.CreatedBy.Email};
       mail.setToAddresses(toAddresses);
       mail.setSubject('Client Ticker Status: ' + a.Status);
       mail.setPlainTextBody
       ('The batch Apex job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures.');
       Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
      
   }
}