this is my main class

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

 public void execute(SchedulableContext sc) { 
        BatchJobContractRetention  obj = new BatchJobContractRetention();
global database.querylocator start(Database.BatchableContext BC) { 

             String query = 'Select Id, Retention__c, contractNumber, Contract_End_Date__c,StartDate,Status__c,Old_Contract_Code__c,New_Contract_Code__c from contract where ((Status__c = \'Expired\' OR Status__c = \'Terminated\' OR Status__c = \'Bankruptcy\') AND Status__c <> \'Executed\') AND (Retention__c <> \'Delete\' AND Retention__c <> \'Retain - Other\' AND Retention__c <> \'Retain – Litigation Hold\') AND ((Old_Contract_Code__c <> null) OR (New_Contract_Code__c <> null)) AND (Contract_End_Date__c <> null)'; 
             //String query = 'Select Id, Retention__c,Contract_End_Date__c,StartDate,Status__c,Old_Contract_Code__c,New_Contract_Code__c from contract where ((Status__c = \'Expired\' OR Status__c = \'Terminated\' OR Status__c = \'Bankruptcy\') AND Status__c <> \'Executed\') AND (Retention__c =  \'Active\' OR Retention__c =  \'Archive\' OR Retention__c =  \'\' ) AND(Contract_End_Date__c <> null)';
             //String query = 'Select Id, Retention__c,Contract_End_Date__c,StartDate,Status__c,Old_Contract_Code__c,New_Contract_Code__c from contract where ((Status__c = \'Expired\' OR Status__c = \'Terminated\' OR Status__c = \'Bankruptcy\') AND Status__c <> \'Executed\') AND (Retention__c =  \'Active\') AND(Contract_End_Date__c <> null)';
             return Database.getQueryLocator(query);

 global void execute(Database.BatchableContext BC, List<Contract> scope) {

            List<Contract> lstContractToUpdate = new List<Contract>();            
            Set<ID> contRetainId = new Set<ID>();             
            Set<String> lstOfCV_Title = new Set<String>(); 
            set<Id> CVID = new Set<Id>();

            /*for (Contract ct : scope) {               
            Map<String , String> mapOfCNNew = new Map<String , String>();
            for (Contract ct : scope) {                                
            Map<string , Contract>  mapOfCNNewStatus = new Map<string , Contract>([Select Id, contractNumber, Status__c from Contract where contractNumber IN : mapOfCNNew.keySet()]);          
            for (Contract ct : scope) {             
                if( ct.New_Contract_Code__c != null && ct.New_Contract_Code__c != '' ) {  
                    for (Contract ctNew : mapOfCNNewStatus.values()){

                        if(ctNew.contractNumber.equals (ct.New_Contract_Code__c)){                                                                                                                       
                              if(ctNew.Status__c != 'Executed')
            List<ContentVersion> CV = [Select Id, contract__c, ContentDocumentId from ContentVersion where contract__c IN : contRetainId ];           
            Date td = Date.today();
            for (Contract ct : scope) {
                    Date newDate = ct.Contract_End_Date__c;
                    Integer y = newDate.year();
                    Integer m = newDate.month();
                    Integer d = newDate.day();              
                    Date contractEndDate = Date.newInstance(y, m, d);
                    Integer numOfDays = contractEndDate.daysBetween(td);
                    Boolean val = numOfDays>2557;
                    system.debug('CV.size()>>>>>>>>>>>>>'+CV.size()>0+'>>>>>>>>>>>>>>>>>>>>>>>>> enddate'+contractEndDate +'no of days   ' + numOfDays+'   value' + val );

                    if(val && CV.size() > 0)
                     ct.Retention__c = 'Archive';


            update lstContractToUpdate ;

            List<ContentVersion> CV1 = [Select contract__r.Id, ContentDocumentId from ContentVersion where contract__r.Id IN : CVID AND contract__r.Retention__c = 'Archive' ];           

            Set<ID> contDocId = new Set<ID>();

            for (ContentVersion d : CV1) {


            List<ContentDocument> CD = [Select Id, ParentId from ContentDocument where Id IN : contDocId ];

            Set<ID> CDId = new Set<ID>();

            Id  TargetWS = [select Id, Name from contentworkspace where name = 'HIPI Retention Library'].id;

            List<ContentDocument> conDocToUpd = new  List<ContentDocument>();

            for (ContentDocument c : CD) {

                    c.ParentId = TargetWS;

            update conDocToUpd;


  global void finish(Database.BatchableContext BC) {

      system.debug('conDocToUpd>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>');



here it is test class

public class BatchJobContractRetentionTest
public static testMethod void helloMethod()
       BatchJobContractRetention a = new BatchJobContractRetention();
        List<Contract> scope = new List<Contract>();
       scope= [Select Id, Retention__c, contractNumber,Contract_End_Date__c,StartDate,Status__c,Old_Contract_Code__c,Ne_Contract_Code__c from contract where ((Status__c = 'Expired' OR Status__c ='Terminated' OR Status__c = 'Bankruptcy') AND Status__c <> 'Executed') AND(Retention__c <> 'Delete' AND Retention__c <> 'Retain - Other' AND Retention__c <> 'Retain – Litigation Hold') AND ((Old_Contract_Code__c <> null) OR (New_Contract_Code__c <> null)) AND (Contract_End_Date__c <> null)];
       Database.BatchableContext bc;
        SchedulableContext sc;
        a.start(BC);                                                                                                                                                                     a.start(BC);
          a.execute(BC, scope);                                                                                                                                                                     


this code is covering 54% code coverage

main problem is that why scope is not having sending data of id and all the things that i selected.and hence scope is not there so it is not passing for() coding in the main class

  • you need to create based on batch logic so when you execute batch then all the condition get satisfy and maximum lines get covered/executes this way you can get the maximum coverage and also don't forget to add asserts to check expected result..
    – Ratan Paul
    May 5, 2016 at 9:04
  • for (Contract ct : scope) for clearing this condition i am sending data through initializing scope in my test class ..but why not data is not sending through list??? May 5, 2016 at 9:08
  • You should think of it as you're not writing a test just to satisfy test coverage but to actually test the batch process which with then improve your core code. As others have mentioned you are missing test data but there are no asserts too! What happens if the batch process fails? Does anyone know its failed? are you doing any logging in the finish method? to say "yup ran as expected" then asserting that? Batch Processes are notorious for breaking based on other changes in code an no-one knowing because they involve no user interaction. Without the assert no dev will know they have broken it.
    – Francis
    May 5, 2016 at 10:08

2 Answers 2


Test classes cannot query data outside that class unless you sepcify @isTest(SeeAllData=true). Any way I don't think you would like to manipulate the actual contract data from the test class.

All you need to do is prepare some test data in the test class. Insert some contracts with the values you are looking for and then run the batch class on the test data. Then it should work as expected. Here is an example.

public class BatchJobContractRetensionTest
    List<Contract> contracts = createContracts();
    Database.executeBatch(new BatchJobContractRetention());
    //Do your assert statements here
static List<Contract> createContracts()
   List<Contract> contracts = new List<Contract>();
   Contract contract1 = new Contract(field1 = value1, field2 = value2);
   Contract contract2 = new Contract(field1 = value1, field2 = value2);
   insert contracts;
   return contracts;

Any lookup fields on the contract, such as AccountId are mandatory then you need to create those records and populate those fields as well before creating contracts. Hope this helps.

  • actually (SeeAllData=true) will burst the code on the deployment thats why i did not coded that.. May 5, 2016 at 9:32
  • That's why I have given you the example of creating the test data in the test class. You don't need to add "seealldata" attribute. Create the test data as in the example and execute the batch as shown in the example. It should work. May 5, 2016 at 13:43

you organisation data will not be visible to your test class if you @istest annotation if you want to see all your organisation data you need to use @istest(seealldata=true) or you have to create the required data in your test class

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .