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
karol.freebergkarol.freeberg 

How do add test code for email class.

Could someone help me write the test code for the below class. I am new at this and don't have a clue on how to write the code for emailing and batch process. What I have so far is below.


global class OpportunityNotices implements Database.Batchable<sObject>,Database.Stateful  
    {  
        Map<Id , List<Opportunity>> userOppMap {get; set;}
        List<Opportunity> allOppNotices {get; set;}
 
              
       global OpportunityNotices()  
       {  
       
           Date CalDate = date.Today().addDays(10);
           
           //Map to maintain user id and cases logged by them today  
           userOppMap = new Map<Id, List<Opportunity>>() ;  
             
           //All sales rep (System admins)  
           List<User> salesRep = new List<User>() ;  
           salesRep = [select id , name , Email from User where isactive = true] ;  
             
           //All sales rep ids  
           List<Id> salesIds = new List<Id>() ;  
           for(User ur : salesRep)  
           {  
               salesIds.add(ur.Id) ;  
           }  
            
           //find a list of Opportuntities with overdue est decision dates
        allOppNotices = new List<Opportunity>();
        allOppNotices = [SELECT Id, StageName, CloseDate, name, OwnerID
            FROM Opportunity 
            WHERE CloseDate <= : CalDate
            AND StageName != 'Closed Won'
            AND StageName != 'Closed Lost'
            Order By OwnerID, ID
        ]; 
  
       }  
      
       global Database.QueryLocator start(Database.BatchableContext BC)  
       {  
          //Creating map of user id with opportunities that are due or overdue  
          for(opportunity c : allOppNotices)  
          {  
              if(userOppMap.containsKey(c.ownerId))  
              {  
                  //Fetch the list of case and add the new case in it  
                  List<Opportunity> tempList = userOppMap.get(c.ownerId) ;  
                  tempList.add(c);  
                  //Putting the refreshed case list in map  
                  userOppMap.put(c.ownerId , tempList) ;  
              }  
              else  
              {  
                  //Creating a list of case and outting it in map  
                  userOppMap.put(c.ownerId , new List<Opportunity>{c}) ;  
              }  
          }  
      
          //Batch on all system admins (sales rep)  
          String query = 'select id , name , Email from User where isactive = true';  
          return Database.getQueryLocator(query);  
       }  
      
       global void execute(Database.BatchableContext BC, List<sObject> scope)  
       {  
             
          for(Sobject s : scope)  
          {  
              //Type cast sObject in user object  
              User ur = (User)s ;  
                
              //If system admin has logged any case today then only mail will be sent  
              if(userOppMap.containsKey(ur.Id))  
              {  
                  //Fetching all cases logged by sys admin  
                  List<Opportunity> allOppOfSalesRep = userOppMap.get(ur.Id) ;  
                    
                  String body = '' ;  
                  //Creating tabular format for the case details  
                  body = BodyFormat(allOppOfSalesRep) ;  
                    
                  //Sending Mail  
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;  
                    
                 //Setting user email in to address  
                  String[] toAddresses = new String[] {ur.Email} ;  
                    
                  // Assign the addresses for the To and CC lists to the mail object  
                  mail.setToAddresses(toAddresses) ;
                  //String[] ccAddresses = new String[] {'ekfree@wctc.net'}; 
                  //mail.setccaddresses(ccaddresses); 
                  mail.setreplyto('_DL_NP_SFDC_ADMIN@newpagecorp.com');
          
                  //Email subject to be changed  
                  mail.setSubject('Opportunity Due Notice');  
                    
                  //Body of email  
                  mail.setHtmlBody('Please review and update the opportunities listed below by updating the estimated decision date or closing the opportunity if it is no longer active. ' 
                   + '<br/> <br/> ' + body + '<br/> ' + 'Thank you.');  
              
                  //Sending the email  
                  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });  
              }  
          }  
       }  
         
       public String BodyFormat(List<Opportunity> opps)  
       {  
           String str = '' ;
             
           for(Opportunity cs : opps)  
           {  
               Date dt = cs.closedate;
               String dateStr = DateTime.newInstance(dt.year(),dt.month(),dt.day()).format('MM/dd/yyyy');
             
               str += '<tr><td colspan="2">'+ cs.Name +'</td>'+'<td colspan="2">'+ dateStr +'</td>'+'<td>'+ '</td>'+'<td>'+ '</td>'+'</tr>' ;  
           }  
           str = str.replace('null' , '') ;  
           String finalStr = '' ;  
           finalStr = '<table border="  "> <td colspan="2">Name </td> <td colspan="2">Est. Decision Date  </td> '+'<td>'+ '</td>'+'<td>'+ '</td>'+ str +'</table>' ;  
           return finalStr ;  
       }  
      
       global void finish(Database.BatchableContext BC)  
       {  
           AsyncApexJob a = [Select id, status, numberoferrors, jobitemsprocessed,
               totaljobitems, createdby.email from AsyncApexJob where id = :BC.getjobid()];
           
           //send email
           Messaging.singleemailmessage mail = new messaging.singleemailmessage();
           string[] toadd = new string[] {'karol.freeberg@newpagecorp.com'};
           mail.settoaddresses(toadd);
           mail.setsubject('Opportunity Notices Job Completed ' + a.status);
           mail.setplaintextbody
               ('The batch apex job processed ' + a.totaljobitems + ' batches with ' + a.numberoferrors + ' failures.');
           messaging.sendemail (new messaging.singleemailmessage[] {mail});
       
       
       }  
      
    }



@isTest class OpportunityNoticesTest {

    Static testmethod void test() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where isactive = true';  
     
     //Test data
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(-16),
        StageName  = 'Target',
        Name = '2014-AARP' + i,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop
     
     Test.starttest();
     Integer batchSize = 1;
     OpportunityNotices OppN = new OpportunityNotices();
     if(!Test.isRunningTest()){
         Database.executeBatch(OppN, batchSize);
     }
     
     Test.StopTest();
     
     
    
    
    } //End testmethod
    
}  //End


Best Answer chosen by karol.freeberg
logontokartiklogontokartik
Ohh Ok. Also the closeDate is 16 days in future and in your apex class you have a condition

@isTest class OpportunityNoticesTest {

    Static testmethod void test() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where isactive = true';  
     
     //Test data
     string LoggedInUSerId = UserInfo.getUserId();
     
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(-16),
        StageName  = 'Target',
        ownerid = LoggedInUSerId,
        Name = '2014-AARP' + i,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop
     insert op; // insert the opportunities
     Test.starttest();
     Integer batchSize = 1;
     OpportunityNotices OppN = new OpportunityNotices();
     
     Test.StopTest();
     
     
    
    
    } //End testmethod

Static testmethod void test2() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where username =  \'' + UserInfo.getUserName() + '\'';  
     
     //Test data
       string LoggedInUSerId2 = UserInfo.getUserId();
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(1), // changed to 1
        StageName  = 'Target',
        Name = '2014-AARP' + i,
        ownerid = LoggedInUSerId2,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop

     insert op; // insert the opportunities
    
      Test.starttest();
       Integer batchSize = 1;
       OpportunityNotices OppN = new OpportunityNotices(query);
       
       Database.executeBatch(OppN, batchSize);
       
     
     Test.StopTest();
    
    } //End testmethod
    
}  //End


All Answers

logontokartiklogontokartik
Hi,
I think you are going in the right direction, but I am not sure why you have !Test.isRunningTest() on line 30. ?? Please remove that line and run your test class.
For the Email, it would execute the lines of code and simulate sending email, you can if you want to capture result, please use sendEmailResult.


https://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_sendemail_emailresult.htm

Hope this helps

James LoghryJames Loghry
About the best you can do is call Limits.getEmailInvocations(); twice. Once before and once after your test runs.  Use that to compare that your email invocations has increased by 1 (or more) signifying that an email will be sent. http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_limits.htm (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_limits.htm)
karol.freebergkarol.freeberg
I have Isrunningtest on line 30 because if I do not have it there, I get this message “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.” As for being close in my code, I cannot be too close. I only have 30% coverage so I for sure need a lot more than what I have.
logontokartiklogontokartik
Hmm. In your test class I see that you are setting the batchsize to 1, so thats not the issue. 

Looking more into your actual batch class, I am not sure why few things are done the way they are done. I made some changes to move code around, can you please try using the below and see if it works.


global class OpportunityNotices implements Database.Batchable<sObject>,Database.Stateful  
    {  
        Map<Id , List<Opportunity>> userOppMap {get; set;}
        List<Opportunity> allOppNotices {get; set;}
        private String query;
              
       global OpportunityNotices()  
       {  
           query = 'select id , name , Email from User where isactive = true';
           Date CalDate = date.Today().addDays(10);
           
           //Map to maintain user id and cases logged by them today  
           userOppMap = new Map<Id, List<Opportunity>>() ;  
             
           //All sales rep (System admins)  
           List<User> salesRep = new List<User>() ;  
           salesRep = [select id , name , Email from User where isactive = true] ;  
             
           //All sales rep ids  
           List<Id> salesIds = new List<Id>() ;  
           for(User ur : salesRep)  
           {  
               salesIds.add(ur.Id) ;  
           }  
            
           //find a list of Opportuntities with overdue est decision dates
        allOppNotices = new List<Opportunity>();
        allOppNotices = [SELECT Id, StageName, CloseDate, name, OwnerID
            FROM Opportunity 
            WHERE CloseDate <= : CalDate
            AND StageName != 'Closed Won'
            AND StageName != 'Closed Lost'
            Order By OwnerID, ID
        ]; 

        //Creating map of user id with opportunities that are due or overdue 
          for(opportunity c : allOppNotices) 
          { 
              if(userOppMap.containsKey(c.ownerId)) 
              { 
                  //Fetch the list of case and add the new case in it 
                  List<Opportunity> tempList = userOppMap.get(c.ownerId) ; 
                  tempList.add(c); 
                  //Putting the refreshed case list in map 
                  userOppMap.put(c.ownerId , tempList) ; 
              } 
              else 
              { 
                  //Creating a list of case and outting it in map 
                  userOppMap.put(c.ownerId , new List<Opportunity>{c}) ; 
              } 
          }
  
       }  
      
       global Database.QueryLocator start(Database.BatchableContext BC)  
       {  
         
      
          //Batch on all system admins (sales rep)  
           
          return Database.getQueryLocator(query);  
       }  
      
       global void execute(Database.BatchableContext BC, List<sObject> scope)  
       {  
             
          for(Sobject s : scope)  
          {  
              //Type cast sObject in user object  
              User ur = (User)s ;  
                
              //If system admin has logged any case today then only mail will be sent  
              if(userOppMap.containsKey(ur.Id))  
              {  
                  //Fetching all cases logged by sys admin  
                  List<Opportunity> allOppOfSalesRep = userOppMap.get(ur.Id) ;  
                    
                  String body = '' ;  
                  //Creating tabular format for the case details  
                  body = BodyFormat(allOppOfSalesRep) ;  
                    
                  //Sending Mail  
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;  
                    
                 //Setting user email in to address  
                  String[] toAddresses = new String[] {ur.Email} ;  
                    
                  // Assign the addresses for the To and CC lists to the mail object  
                  mail.setToAddresses(toAddresses) ;
                  //String[] ccAddresses = new String[] {'ekfree@wctc.net'}; 
                  //mail.setccaddresses(ccaddresses); 
                  mail.setreplyto('_DL_NP_SFDC_ADMIN@newpagecorp.com');
          
                  //Email subject to be changed  
                  mail.setSubject('Opportunity Due Notice');  
                    
                  //Body of email  
                  mail.setHtmlBody('Please review and update the opportunities listed below by updating the estimated decision date or closing the opportunity if it is no longer active. ' 
                   + '<br/> <br/> ' + body + '<br/> ' + 'Thank you.');  
              
                  //Sending the email  
                  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });  
              }  
          }  
       }  
         
       public String BodyFormat(List<Opportunity> opps)  
       {  
           String str = '' ;
             
           for(Opportunity cs : opps)  
           {  
               Date dt = cs.closedate;
               String dateStr = DateTime.newInstance(dt.year(),dt.month(),dt.day()).format('MM/dd/yyyy');
             
               str += '<tr><td colspan="2">'+ cs.Name +'</td>'+'<td colspan="2">'+ dateStr +'</td>'+'<td>'+ '</td>'+'<td>'+ '</td>'+'</tr>' ;  
           }  
           str = str.replace('null' , '') ;  
           String finalStr = '' ;  
           finalStr = '<table border="  "> <td colspan="2">Name </td> <td colspan="2">Est. Decision Date  </td> '+'<td>'+ '</td>'+'<td>'+ '</td>'+ str +'</table>' ;  
           return finalStr ;  
       }  
      
       global void finish(Database.BatchableContext BC)  
       {  
           AsyncApexJob a = [Select id, status, numberoferrors, jobitemsprocessed,
               totaljobitems, createdby.email from AsyncApexJob where id = :BC.getjobid()];
           
           //send email
           Messaging.singleemailmessage mail = new messaging.singleemailmessage();
           string[] toadd = new string[] {'karol.freeberg@newpagecorp.com'};
           mail.settoaddresses(toadd);
           mail.setsubject('Opportunity Notices Job Completed ' + a.status);
           mail.setplaintextbody
               ('The batch apex job processed ' + a.totaljobitems + ' batches with ' + a.numberoferrors + ' failures.');
           messaging.sendemail (new messaging.singleemailmessage[] {mail});
       
       
       }  
      
    }



karol.freebergkarol.freeberg
Code is at 27% coverage. The changes in the class itself did not change code coverage. I also added getemailinvocations before and after the test and did a system assert to show they changed and that did not help.
karol.freebergkarol.freeberg
This did not do the trick. Still way low.
logontokartiklogontokartik
Yes. That makes sense, because when you create the opportunities the owner Id is the current user running the test, which is you. But when you run your Batch Apex, when query does the user select, it retrieves all users and the first active user is pulled in the batch, which might be you, might not be you. Hence its not going into your "if loop on line 74". Can you add another constructor for you batch class? and add another test method? something like below.

global class OpportunityNotices implements Database.Batchable<sObject>,Database.Stateful  
    {  
        Map<Id , List<Opportunity>> userOppMap {get; set;}
        List<Opportunity> allOppNotices {get; set;}
        private String query;
      
     global OpportunityNotices(String q)  
       {  
           query = q;
           init(); 
     }
        
       global OpportunityNotices()  
       {  
           query = 'select id , name , Email from User where isactive = true';
           init();
       }  

      private void init(){
             Date CalDate = date.Today().addDays(10);
           
           //Map to maintain user id and cases logged by them today  
           userOppMap = new Map<Id, List<Opportunity>>() ;  
             
           //All sales rep (System admins)  
           List<User> salesRep = new List<User>() ;  
           salesRep = [select id , name , Email from User where isactive = true] ;  
             
           //All sales rep ids  
           List<Id> salesIds = new List<Id>() ;  
           for(User ur : salesRep)  
           {  
               salesIds.add(ur.Id) ;  
           }  
            
           //find a list of Opportuntities with overdue est decision dates
        allOppNotices = new List<Opportunity>();
        allOppNotices = [SELECT Id, StageName, CloseDate, name, OwnerID
            FROM Opportunity 
            WHERE CloseDate <= : CalDate
            AND StageName != 'Closed Won'
            AND StageName != 'Closed Lost'
            Order By OwnerID, ID
        ]; 

        //Creating map of user id with opportunities that are due or overdue 
          for(opportunity c : allOppNotices) 
          { 
              if(userOppMap.containsKey(c.ownerId)) 
              { 
                  //Fetch the list of case and add the new case in it 
                  List<Opportunity> tempList = userOppMap.get(c.ownerId) ; 
                  tempList.add(c); 
                  //Putting the refreshed case list in map 
                  userOppMap.put(c.ownerId , tempList) ; 
              } 
              else 
              { 
                  //Creating a list of case and outting it in map 
                  userOppMap.put(c.ownerId , new List<Opportunity>{c}) ; 
              } 
          }
     }
      
       global Database.QueryLocator start(Database.BatchableContext BC)  
       {  
         
      
          //Batch on all system admins (sales rep)  
           
          return Database.getQueryLocator(query);  
       }  
      
       global void execute(Database.BatchableContext BC, List<sObject> scope)  
       {  
             
          for(Sobject s : scope)  
          {  
              //Type cast sObject in user object  
              User ur = (User)s ;  
                
              //If system admin has logged any case today then only mail will be sent  
              if(userOppMap.containsKey(ur.Id))  
              {  
                  //Fetching all cases logged by sys admin  
                  List<Opportunity> allOppOfSalesRep = userOppMap.get(ur.Id) ;  
                    
                  String body = '' ;  
                  //Creating tabular format for the case details  
                  body = BodyFormat(allOppOfSalesRep) ;  
                    
                  //Sending Mail  
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;  
                    
                 //Setting user email in to address  
                  String[] toAddresses = new String[] {ur.Email} ;  
                    
                  // Assign the addresses for the To and CC lists to the mail object  
                  mail.setToAddresses(toAddresses) ;
                  //String[] ccAddresses = new String[] {'ekfree@wctc.net'}; 
                  //mail.setccaddresses(ccaddresses); 
                  mail.setreplyto('_DL_NP_SFDC_ADMIN@newpagecorp.com');
          
                  //Email subject to be changed  
                  mail.setSubject('Opportunity Due Notice');  
                    
                  //Body of email  
                  mail.setHtmlBody('Please review and update the opportunities listed below by updating the estimated decision date or closing the opportunity if it is no longer active. ' 
                   + '<br/> <br/> ' + body + '<br/> ' + 'Thank you.');  
              
                  //Sending the email  
                  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });  
              }  
          }  
       }  
         
       public String BodyFormat(List<Opportunity> opps)  
       {  
           String str = '' ;
             
           for(Opportunity cs : opps)  
           {  
               Date dt = cs.closedate;
               String dateStr = DateTime.newInstance(dt.year(),dt.month(),dt.day()).format('MM/dd/yyyy');
             
               str += '<tr><td colspan="2">'+ cs.Name +'</td>'+'<td colspan="2">'+ dateStr +'</td>'+'<td>'+ '</td>'+'<td>'+ '</td>'+'</tr>' ;  
           }  
           str = str.replace('null' , '') ;  
           String finalStr = '' ;  
           finalStr = '<table border="  "> <td colspan="2">Name </td> <td colspan="2">Est. Decision Date  </td> '+'<td>'+ '</td>'+'<td>'+ '</td>'+ str +'</table>' ;  
           return finalStr ;  
       }  
      
       global void finish(Database.BatchableContext BC)  
       {  
           AsyncApexJob a = [Select id, status, numberoferrors, jobitemsprocessed,
               totaljobitems, createdby.email from AsyncApexJob where id = :BC.getjobid()];
           
           //send email
           Messaging.singleemailmessage mail = new messaging.singleemailmessage();
           string[] toadd = new string[] {'karol.freeberg@newpagecorp.com'};
           mail.settoaddresses(toadd);
           mail.setsubject('Opportunity Notices Job Completed ' + a.status);
           mail.setplaintextbody
               ('The batch apex job processed ' + a.totaljobitems + ' batches with ' + a.numberoferrors + ' failures.');
           messaging.sendemail (new messaging.singleemailmessage[] {mail});
       
       
       }  
      
    }

Your test class would be 


@isTest class OpportunityNoticesTest {

    Static testmethod void test() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where isactive = true';  
     
     //Test data
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(-16),
        StageName  = 'Target',
        Name = '2014-AARP' + i,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop
     
     Test.starttest();
     Integer batchSize = 1;
     OpportunityNotices OppN = new OpportunityNotices();
     Database.executeBatch(OppN, batchSize);
     
     Test.StopTest();
     
     
    
    
    } //End testmethod

Static testmethod void test2() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where username =  \'' + UserInfo.getUserName() + '\'';  
     
     //Test data
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(-16),
        StageName  = 'Target',
        Name = '2014-AARP' + i,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop
     
     Test.starttest();
       Integer batchSize = 1;
       OpportunityNotices OppN = new OpportunityNotices(query);
       Database.executeBatch(OppN, batchSize);
     
     Test.StopTest();
    
    } //End testmethod
    
}  //End

PS: I have not added asserts, Please make sure that you add asserts to test classes wherever needed



karol.freebergkarol.freeberg
Cannot do this line. OpportunityNotices OppN = new OpportunityNotices(query); OpportunityNotices does not accept query parameter. I get a construct error.
logontokartiklogontokartik
Hi, Did you change your Batch class to include the constructor? Please look at the code I pasted above . Thank you
karol.freebergkarol.freeberg
Opps, OK did took care of that and ran again. Up to 33%. Can’t say I’ve ever had that much trouble with a test before. (Except this is only like the 5th one I’ve done. Lol.)
logontokartiklogontokartik
Really!!!. Ahh... Can you look at the lines that are not covered... (copy/paste screenshot if possible)? Its weird thing to happen. Also when you create your test Opp Data, can you explicitly assign OwnerId to your userId? Like 

o.OwnerId = UserInfo.getUserId();
logontokartiklogontokartik
Also add some assert statements after you insert opportunities, like 

system.assertEquals(o.OwnerId,UserInfo.getUserId());

or

List<Opportunity> newlyInserted = [Select Id, Name from Opportunity where OwnerId = :UserInfo.getUserId()];
system.assertEquals(5,newlyInserted.size());

karol.freebergkarol.freeberg
Below is what I have right now in the class and test. I think I will review how I'm getting the user ids. When I just run the job using the dev console, the final email tells me I have 209 batches. Basically that is 209 active users. I don't need all that so I'll review that; however, don't think that will change that percentage.
global class OpportunityNotices implements Database.Batchable<sObject>,Database.Stateful  
    {  
        Map<Id , List<Opportunity>> userOppMap {get; set;}
        List<Opportunity> allOppNotices {get; set;}
        private String query;
              
       global OpportunityNotices(string q)  
       {  
            query = q;
            init(); 
       }
       
        global OpportunityNotices()  
        {
       
           query = 'select id , name , Email from User where isactive = true';
           init();
           
        }
        
        private void init()
        {
           Date CalDate = date.Today().addDays(10);
           
           //Map to maintain user id and cases logged by them today  
           userOppMap = new Map<Id, List<Opportunity>>() ;  
             
           //All sales rep (System admins)  
           List<User> salesRep = new List<User>() ;  
           salesRep = [select id , name , Email from User where isactive = true] ;  
             
           //All sales rep ids  
           List<Id> salesIds = new List<Id>() ;  
           for(User ur : salesRep)  
           {  
               salesIds.add(ur.Id) ;  
           }  
            
           //find a list of Opportuntities with overdue est decision dates
        allOppNotices = new List<Opportunity>();
        allOppNotices = [SELECT Id, StageName, CloseDate, name, OwnerID
            FROM Opportunity 
            WHERE CloseDate <= : CalDate
            AND StageName != 'Closed Won'
            AND StageName != 'Closed Lost'
            Order By OwnerID, ID
        ]; 

        //Creating map of user id with opportunities that are due or overdue 
          for(opportunity c : allOppNotices) 
          { 
              if(userOppMap.containsKey(c.ownerId)) 
              { 
                  //Fetch the list of case and add the new case in it 
                  List<Opportunity> tempList = userOppMap.get(c.ownerId) ; 
                  tempList.add(c); 
                  //Putting the refreshed case list in map 
                  userOppMap.put(c.ownerId , tempList) ; 
              } 
              else 
              { 
                  //Creating a list of case and outting it in map 
                  userOppMap.put(c.ownerId , new List<Opportunity>{c}) ; 
              } 
          }
  
       }  
      
       global Database.QueryLocator start(Database.BatchableContext BC)  
       {  
         
      
          //Batch on all system admins (sales rep)  
           
          return Database.getQueryLocator(query);  
       }  
      
       global void execute(Database.BatchableContext BC, List<sObject> scope)  
       {  
             
          for(Sobject s : scope)  
          {  
              //Type cast sObject in user object  
              User ur = (User)s ;  
                
              //If system admin has logged any case today then only mail will be sent  
              if(userOppMap.containsKey(ur.Id))  
              {  
                  //Fetching all cases logged by sys admin  
                  List<Opportunity> allOppOfSalesRep = userOppMap.get(ur.Id) ;  
                    
                  String body = '' ;  
                  //Creating tabular format for the case details  
                  body = BodyFormat(allOppOfSalesRep) ;  
                    
                  //Sending Mail  
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;  
                    
                 //Setting user email in to address  
                  String[] toAddresses = new String[] {ur.Email} ;  
                    
                  // Assign the addresses for the To and CC lists to the mail object  
                  mail.setToAddresses(toAddresses) ;
                  //String[] ccAddresses = new String[] {'ekfree@wctc.net'}; 
                  //mail.setccaddresses(ccaddresses); 
                  mail.setreplyto('_DL_NP_SFDC_ADMIN@newpagecorp.com');
          
                  //Email subject to be changed  
                  mail.setSubject('Opportunity Due Notice');  
                    
                  //Body of email  
                  mail.setHtmlBody('Please review and update the opportunities listed below by updating the estimated decision date or closing the opportunity if it is no longer active. ' 
                   + '<br/> <br/> ' + body + '<br/> ' + 'Thank you.');  
              
                  //Sending the email  
                  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });  
              }  
          }  
       }  
         
       public String BodyFormat(List<Opportunity> opps)  
       {  
           String str = '' ;
             
           for(Opportunity cs : opps)  
           {  
               Date dt = cs.closedate;
               String dateStr = DateTime.newInstance(dt.year(),dt.month(),dt.day()).format('MM/dd/yyyy');
             
               str += '<tr><td colspan="2">'+ cs.Name + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' + '</td>'+'<td colspan="2">'+ dateStr +'</td>'+'<td>'+ '</td>'+'<td>'+ '</td>'+'</tr>' ;  
           }  
           str = str.replace('null' , '') ;  
           String finalStr = '' ;  
           finalStr = '<table border="  "> <td colspan="2">Name </td> <td colspan="2">Est. Decision Date  </td> '+'<td>'+ '</td>'+'<td>'+ '</td>'+ str +'</table>' ;  
           return finalStr ;  
       }  
      
       global void finish(Database.BatchableContext BC)  
       {  
           AsyncApexJob a = [Select id, status, numberoferrors, jobitemsprocessed,
               totaljobitems, createdby.email from AsyncApexJob where id = :BC.getjobid()];
           
           //send email
           Messaging.singleemailmessage mail = new messaging.singleemailmessage();
           string[] toadd = new string[] {'karol.freeberg@newpagecorp.com'};
           mail.settoaddresses(toadd);
           mail.setsubject('Opportunity Notices Job Completed ' + a.status);
           mail.setplaintextbody
               ('The batch apex job processed ' + a.totaljobitems + ' batches with ' + a.numberoferrors + ' failures.');
           messaging.sendemail (new messaging.singleemailmessage[] {mail});
       
       
       }  
      
    }
@isTest class OpportunityNoticesTest {

    Static testmethod void test() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where isactive = true';  
     
     //Test data
     string LoggedInUSerId = UserInfo.getUserId();
     
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(-16),
        StageName  = 'Target',
        ownerid = LoggedInUSerId,
        Name = '2014-AARP' + i,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop
     
     Test.starttest();
     Integer batchSize = 1;
     OpportunityNotices OppN = new OpportunityNotices();
     if(!Test.isRunningTest()){
         Database.executeBatch(OppN, batchSize);
     }
     
     Test.StopTest();
     
     
    
    
    } //End testmethod

Static testmethod void test2() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where username =  \'' + UserInfo.getUserName() + '\'';  
     
     //Test data
       string LoggedInUSerId2 = UserInfo.getUserId();
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(16),
        StageName  = 'Target',
        Name = '2014-AARP' + i,
        ownerid = LoggedInUSerId2,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop
     
     Test.starttest();
       Integer batchSize = 1;
       OpportunityNotices OppN = new OpportunityNotices(query);
       if(!Test.isRunningTest()){
           Database.executeBatch(OppN, batchSize);
       }
     
     Test.StopTest();
    
    } //End testmethod
    
}  //End



karol.freebergkarol.freeberg
How can I tell what lines of code are not covered. Sorry for being such a newbie. Some day they will let me go to training but it will probably be a few months yet. 
karol.freebergkarol.freeberg
I did two things. First commended out the lists relating to the sales rep ids. They were not really used. Big thing was to add the insert of the new opportunities after creating them and adding them to the list, they were never inserted. So now the asserts checking for the newly inserted opportunities passes. But still only at 37%.
logontokartiklogontokartik
Ohh Ok. Also the closeDate is 16 days in future and in your apex class you have a condition

@isTest class OpportunityNoticesTest {

    Static testmethod void test() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where isactive = true';  
     
     //Test data
     string LoggedInUSerId = UserInfo.getUserId();
     
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(-16),
        StageName  = 'Target',
        ownerid = LoggedInUSerId,
        Name = '2014-AARP' + i,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop
     insert op; // insert the opportunities
     Test.starttest();
     Integer batchSize = 1;
     OpportunityNotices OppN = new OpportunityNotices();
     
     Test.StopTest();
     
     
    
    
    } //End testmethod

Static testmethod void test2() {
    
    //query used by the batch job
     String query = 'select id , name , Email from User where username =  \'' + UserInfo.getUserName() + '\'';  
     
     //Test data
       string LoggedInUSerId2 = UserInfo.getUserId();
     Opportunity[] op = new List<opportunity>();
     For (integer i=0; i < 5;i++) {
     
        Opportunity o = new opportunity(
        Closedate  = date.Today().addDays(1), // changed to 1
        StageName  = 'Target',
        Name = '2014-AARP' + i,
        ownerid = LoggedInUSerId2,
        reason_won_lost__C = 'Freight;History',
        annual_volume__c = 3,
        type = 'New Business',
        tons_won__c = 15,
        frequency__c = 'Spot',
        End_Use__c = 'This is the end use',
        start_Date__c = date.today());
        op.add(o);
     
     } //End for loop

     insert op; // insert the opportunities
    
      Test.starttest();
       Integer batchSize = 1;
       OpportunityNotices OppN = new OpportunityNotices(query);
       
       Database.executeBatch(OppN, batchSize);
       
     
     Test.StopTest();
    
    } //End testmethod
    
}  //End


This was selected as the best answer
logontokartiklogontokartik
Please try above, I tested it and I got 96% code coverage.
karol.freebergkarol.freeberg
OK, that did it. Once I added the inserts I could take out the isrunning thing and not get an error message. Before that it would not save. This was truly a learning lesson. I can't get to that training soon enough. Considering I've been working with apex for 2 1/2 months inbetween my regular work load, this is not too bad.  

Thank you so much for your help!!!!! You managed to turn a fustrating situation into something of value. Thanks again!
karol.freebergkarol.freeberg
By the way, I'm at 100%.

logontokartiklogontokartik
Glad that I was able to help. Thank you and keep coding... :)