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
AlpsPSO CommunityAlpsPSO Community 

URGENT HELP REQUIRED FOR CODE COVERAGE FOR SCHEDULED APEX CLASS

Hello,

 

Can anyone help me in code coverage for the below sample code. Its really urgent for the Production. The code is fine in Sandbox :

 

Main class :

 

/************************************************************************************************************************

 

global class NotificationScheduledFor40Hours implements Schedulable {

//public static String userProfileID = '';

    global void execute(SchedulableContext ctx) {       
      
         sendEmail();
    }
   
    private void sendEmail(){   
           
        for( User  u : [SELECT id,ProfileId,FirstName,Email,Total_hours_of_week__c FROM User WHERE User.Total_hours_of_week__c <: 40.00 limit 1000] ){
       
                String email = u.Email;
                String userProfileID = u.ProfileId;
                String userEmail = u.Email;
        }
    }

}

 

/************************************************************************************************************************

 

Test class as below :

 

 

/************************************************************************************************************************

 @istest
private class EmailTestClass {

static testmethod void EmailTest(){
   
    List<User> userList = new List<User>();
   
    Profile profile = [select id from profile where name='Consultant User'];
    User u = new User(alias = 'cons', email='standarduserEmail@testorg.com',
        emailencodingkey='UTF-8', lastname='nameL', languagelocalekey='en_US',
        localesidkey='en_US', profileid = profile.Id,
        timezonesidkey='America/Los_Angeles', username='standardusername@testorg.com');
   
    insert u;
   
    u.put('FirstName', 'nameF');   
    u.put('Total_hours_of_week__c',10.00);
   
    update u;
   
    userList.add(u);
   
    System.assert(true,userList);
   
    if ( userList.isEmpty()) system.debug('No user found');
   
    else {
   
    System.assert(true,u);
    System.assertEquals(u.FirstName, 'nameF');
    System.assertEquals(u.Email, 'standarduserEmail@testorg.com');
    System.assertEquals(u.ProfileId, '00e80000000l0tQAAQ');
   
    String firstName = u.FirstName;
    String uProfileId = u.ProfileId;
    String email = u.Email;   
   
    System.debug('firstName : ' + firstName);
    System.debug('Profile id : ' + uProfileId);
    System.debug('email : ' + email);
    }
}
}

/************************************************************************************************************************



Please let m eknow hat i am missing.

Best Answer chosen by Admin (Salesforce Developers) 
SteveBowerSteveBower

 

It's very late and I'm just typing this in because there is just too much in your code that just doesn't make sense.   I'm sure there will be spelling, syntax, etc. errors.

 

Hopefully this will get you on the right path with both the class and the testing.  

 

I STRONGLY encourage you to use comments throughout your code.  They will help you think through what you are trying to do if you write them like a story that has to hang together.   Don't do it as an afterthought, do it as you write the code, or even before like an outline.

 

Best, Steve.

 

 

 

global class NotificationScheduledFor40Hours implements Schedulable {
   
  global void execute(SchedulableContext ctx) {
doMail();
}
public void doMail() { // Load the Profiles we want to compare against. Profile ConsultantProfile = [select id from profile where name='Consultant User']; Profile ProjectManagerProfile = [select id from profile where name='Project Manager']; // A place to hold the messages we're going to send List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>(); // A place to hold the Users we're going to check List<User> users = new List<User>([SELECT id,ProfileId,FirstName,Email,Total_hours_of_week__c FROM User WHERE User.Total_hours_of_week__c <: 40.00 limit 1000]); // A place to hold the Users we're going to update. (Can't just use 'users' because we won't update all of them, only the ones with the right profiles) List<User> usersToUpdate = new List<User>(); // Loop through the users we want to send messages to. for (User u: users) { system.debug('u is :: ' + u); // If the user isn't a Consultant or Project Manager, Skip them. if (u.ProfileId != ProjectManagerProfile.id && u.ProfileId != ConsultantProfile.id) continue; // Reset their hours u.Total_hours_of_week__c = 0.0; usersToUpdate.add(u); // Build a message for that user. Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); mail.setToAddresses(u.Email); mail.setsubject('Less Than 40 Hours for Last Week.'); mail.setHtmlBody('You have less than 40 hours entered in Salesforce.com for last week. Please update your hours or enter PTO. If you have questions or are unable to enter your hours, please contact your System Administrator.'); // Add it to the list of emails to send. emails.add(mail); } // If we have messages to send, send them and update the users. if (!emails.isEmpty()) { Messaging.sendEmail(emails); update usersToUpdate; } }

 

 

@istest
private class EmailTestClass {

    static testmethod void EmailTest(){
   
         Test.startTest();

        // Load the Profiles we want to compare against.
        Profile ConsultantProfile = [select id from profile where name='Consultant User'];
        Profile ProjectManagerProfile = [select id from profile where name='Project Manager'];
   
        User u = new User(
             FirstName= = 'nameF',
             Total_hours_of_week__c = 10.0,
             alias = 'cons', 
             email='nchandel@qasource.com',
             emailencodingkey='UTF-8', 
             lastname='nameL', 
             languagelocalekey='en_US',
             localesidkey='en_US', 
             profileid = ConsultantProfile.Id,
             timezonesidkey='America/Los_Angeles', 
             username='standardusername@testorg.com');
   
    insert u;
   
    system.assertNotEquals(null, u.id);    
   
    NotificationScheduledFor40Hours give40 = new NotificationScheduledFor40Hours();
    give40.doMail();  

    // Verify that the users hours have been reset
    assertEquals(0.0, [select Total_hours_of_week__c from User where id=:u.id].Total_hours_of_week__c); 
     
    Test.stopTest(); 
}

 

 

 

 

 

 

 

 

 

 

All Answers

SteveBowerSteveBower

I generall applaud doing the testing code early in the process, but before you worry too much further about the code coverage you might take a look at your sendEmail code which, while setting a lot of Strings in the loop, isn't actually trying to send any e-mail.   Look into the Email classes in the Apex documentation.

 

 

Regarding testing:

1. This: System.assert(true,userList);  is equivalent to:    System.assert(userList), which is meaningless since userList isn't a boolean.  Figure out what you were trying to assert here.

 

 

2. Here:

    userList.add(u);

    System.assert(true,userList);   

    if ( userList.isEmpty()) system.debug('No user found');

 

How could userList be empty, you just inserted it above?

 

3. But overall, you're trying to test if an e-mail message was sent.  So, there are two things you're trying to do here, one is getting test code coverage, and the other is to make sure that the e-mail message is actually being sent.  

 

You'll get test code coverage just by calling your sendEmail method.  

 

However, there is no *easy* way of checking, in Salesforce, that the message was actually sent.  So, this is one of those instances where you run the test code just to get the coverage and actually check the results manually.  e.g. make sure that somebody actually got the e-mail message... use your own e-mail address in the test data. 

 

So, your test code just needs to:

1. Create a Profile and insert it.

1. Create a user record, using that profile, with your e-mail address, with less than 40 hours.

2. Insert it.

3. system.assertNotEquals(null, u.id); // Just to make sure it was inserted properly... this isn't testing *your* code yet.

4. NotificationScheduledFor40Hours x = new NotificationScheduledFor40Hours ();

5. x.sendEmail();

 

Now go check your e-mail and make sure you got a message.

 

Hope this helps, Best, Steve.

 

 

 

 

AlpsPSO CommunityAlpsPSO Community

Hi Steve,

 

Thanks a lot for your help. I followed all your steps. But i am still facing error :

 

Main class to be scheduled : But i am not able to save it to Prodcution instance using Force.com IDE. It says i have 73% code coverage.

 

/*******************************************************************************************************************

global class NotificationScheduledFor40Hours implements Schedulable {

   
        private final List<Id> contactids = new List<Id>();
        private final List<Id> userIds = new List<Id>();
        private final List<User> userList = new List<User>();
        private final List<String> emailAddressList = new List<String>();   
   
        global void execute(SchedulableContext ctx) {
   
        List<User>  u = [SELECT id,ProfileId,FirstName,Email,Total_hours_of_week__c FROM User WHERE User.Total_hours_of_week__c <: 40.00 limit 1000];
       
        if(! u.isEmpty()){
           
            system.debug('u is :: ' + u);

             for(Integer i=0;i<u.size();i++)
             {
                User u1 = u[i];                
                 
                System.debug('u1::' + u1);
               
                String userFirstName = u1.FirstName;
               
                String conultantProfileID = '00e80000000l0tQAAQ';               
                String projectManagerProfileID = '00e80000000l14jAAA';
               
                String userProfileID = u1.ProfileId;
               
                if ( ( userProfileID != null || userProfileID != '') && ( conultantProfileID.equals(userProfileID) || projectManagerProfileID.equals(userProfileID)) ) {
                userIds.add(u1.id);       
               
                userList.add(u1); 
                String emailString = u1.Email;
                emailAddressList.add(emailString);    
                //Id contactID = u1.ContactId;
                //System.debug('contactID ::' + contactID);
                System.debug('emailString ::' + u1.Email);
       
                
                 String[] toAddressList = new String[]{};
   
                for(Integer j=0;j<emailAddressList.size();j++){
                    String emailID = emailAddressList.get(j);
                    toAddressList.add(emailID);
                }
                
                 Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                //String toaddress = toAddressList.get(i);
                mail.setToAddresses(toAddressList);
                mail.setsubject('Less Than 40 Hours for Last Week.');
                mail.setHtmlBody('You have less than 40 hours entered in Salesforce.com for last week.  Please update your hours or enter PTO.  If you have questions or are unable to enter your hours, please contact your System Administrator.');
                Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
                system.debug('Email sent to :: ' + mail);
               
                u1.put('Total_hours_of_week__c',0.00);
                 update u1;
               }
              }
            }                                  
     }
}

/*******************************************************************************************************************

 

Test Class :

 

/*******************************************************************************************************************

@istest
private class EmailTestClass {

static testmethod void EmailTest(){
   
    Test.startTest();
   
   
    Profile profile = [select id from profile where name='Consultant User'];
    User u = new User(alias = 'cons', email='nchandel@qasource.com',
        emailencodingkey='UTF-8', lastname='nameL', languagelocalekey='en_US',
        localesidkey='en_US', profileid = profile.Id,
        timezonesidkey='America/Los_Angeles', username='standardusername@testorg.com');
   
    insert u;
   
    system.assertNotEquals(null, u.id);    
   
    u.put('FirstName', 'nameF');    
    u.put('Total_hours_of_week__c',10.00);
    u.ProfileId = '00e80000000l0tQAAQ';
   
    update u;
   
       
   
    List<User>  uList = [SELECT id,ProfileId,FirstName,Email,Total_hours_of_week__c FROM User WHERE User.Total_hours_of_week__c <: 40.00 limit 1];
       
        if(! uList.isEmpty()){
           
            system.debug('u is :: ' + uList);

             for(Integer i=0;i<uList.size();i++)
             {
                User u1 = uList[i];                
                 
                System.debug('u1::' + u1);
               
                String userFirstName = u1.FirstName;
            }
        }                                        
     
    Test.stopTest(); 
}
}

/*******************************************************************************************************************

 

I tried to create and insert new Profile as below :

 

/**************************

Profile newProfile = new Profile();
 newProfile.Name = 'testProfile';   
  system.assertNotEquals(null, newProfile.id);

/**************************

 

Also, please let me know how can i call this :

 NotificationScheduledFor40Hours x = new NotificationScheduledFor40Hours();
x.sendEmail();

 

Untill i can save my Apex class to Production instance. The code is showing method does not exist.

 

 

 

 

SteveBowerSteveBower

 

It's very late and I'm just typing this in because there is just too much in your code that just doesn't make sense.   I'm sure there will be spelling, syntax, etc. errors.

 

Hopefully this will get you on the right path with both the class and the testing.  

 

I STRONGLY encourage you to use comments throughout your code.  They will help you think through what you are trying to do if you write them like a story that has to hang together.   Don't do it as an afterthought, do it as you write the code, or even before like an outline.

 

Best, Steve.

 

 

 

global class NotificationScheduledFor40Hours implements Schedulable {
   
  global void execute(SchedulableContext ctx) {
doMail();
}
public void doMail() { // Load the Profiles we want to compare against. Profile ConsultantProfile = [select id from profile where name='Consultant User']; Profile ProjectManagerProfile = [select id from profile where name='Project Manager']; // A place to hold the messages we're going to send List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>(); // A place to hold the Users we're going to check List<User> users = new List<User>([SELECT id,ProfileId,FirstName,Email,Total_hours_of_week__c FROM User WHERE User.Total_hours_of_week__c <: 40.00 limit 1000]); // A place to hold the Users we're going to update. (Can't just use 'users' because we won't update all of them, only the ones with the right profiles) List<User> usersToUpdate = new List<User>(); // Loop through the users we want to send messages to. for (User u: users) { system.debug('u is :: ' + u); // If the user isn't a Consultant or Project Manager, Skip them. if (u.ProfileId != ProjectManagerProfile.id && u.ProfileId != ConsultantProfile.id) continue; // Reset their hours u.Total_hours_of_week__c = 0.0; usersToUpdate.add(u); // Build a message for that user. Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); mail.setToAddresses(u.Email); mail.setsubject('Less Than 40 Hours for Last Week.'); mail.setHtmlBody('You have less than 40 hours entered in Salesforce.com for last week. Please update your hours or enter PTO. If you have questions or are unable to enter your hours, please contact your System Administrator.'); // Add it to the list of emails to send. emails.add(mail); } // If we have messages to send, send them and update the users. if (!emails.isEmpty()) { Messaging.sendEmail(emails); update usersToUpdate; } }

 

 

@istest
private class EmailTestClass {

    static testmethod void EmailTest(){
   
         Test.startTest();

        // Load the Profiles we want to compare against.
        Profile ConsultantProfile = [select id from profile where name='Consultant User'];
        Profile ProjectManagerProfile = [select id from profile where name='Project Manager'];
   
        User u = new User(
             FirstName= = 'nameF',
             Total_hours_of_week__c = 10.0,
             alias = 'cons', 
             email='nchandel@qasource.com',
             emailencodingkey='UTF-8', 
             lastname='nameL', 
             languagelocalekey='en_US',
             localesidkey='en_US', 
             profileid = ConsultantProfile.Id,
             timezonesidkey='America/Los_Angeles', 
             username='standardusername@testorg.com');
   
    insert u;
   
    system.assertNotEquals(null, u.id);    
   
    NotificationScheduledFor40Hours give40 = new NotificationScheduledFor40Hours();
    give40.doMail();  

    // Verify that the users hours have been reset
    assertEquals(0.0, [select Total_hours_of_week__c from User where id=:u.id].Total_hours_of_week__c); 
     
    Test.stopTest(); 
}

 

 

 

 

 

 

 

 

 

 

This was selected as the best answer
AlpsPSO CommunityAlpsPSO Community

Thanks Steve for all your help and guidance.

 

I know while posting our messages we should be careful for the spelling, syntax, etc. errors. I will be surely following that from now onwards. Morever I am just new to Salesforce and Apex development thats why i am careless while code handling.

 

Moreover, i tried your code and it worked AWESOME....:smileyhappy:. We are bale achieve 83% of code coverage. 

 

I will be using ypur this help for understanding further test cases and code coverage.

 

Now i have to work for 2 more rule triggers and then have to schedule this apex for them I will be doing that now and will surely let you know for any help or guideance.

 

However, i have a question.. I am getting below error for the code :

 

mail.setToAddresses(u.Email);

 



 

Due to this i have to use below syntax for each user :

 

/***********************************************************************************************

 

String[] emailAddressList = new String[]{};
String emailString = u.Email;
emailAddressList.add(emailString);
               
String[] toAddressList = new String[]{};
   
for(Integer j=0;j<emailAddressList.size();j++){
    String emailID = emailAddressList.get(j);
    toAddressList.add(emailID);
}
mail.setToAddresses(toAddressList);
mail.setsubject('Less Than 40 Hours for Last Week.');
mail.setHtmlBody('You have less than 40 hours entered in Salesforce.com for last week. Please update your hours or enter PTO. If you have questions or are unable to enter your hours, please contact your System Administrator.');
// Send the email to the user if mail is not null
if ( mail != null ){
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
system.debug('Email sent to :: ' + mail);                
u.put('Total_hours_of_week__c',0.00);
update u;
}

 

/***********************************************************************************************

 

Please advice me whether its APex verison related or i am doing somewhere wrong.

 

Again,

Thanks a lot for all your help..

 

 

 

 

 

 

SteveBowerSteveBower

My mistake, I didn't look at the parameter for the setToAddresses.  Since it takes more than one e-mail address, and you're sending the exact same message to everybody, then you could accumulate the e-mail addresses in a List and just use that in ONE Messaging.SingleEmailMessage call.  OR, you could just make it an array of size=1 and use multiple SingleEmailMessages....  There is a limit of 100 e-mail addresses in one call, so it sort of depends on how many people you are going to be sending messages to.  

 

So, it's either this:  which uses one e-mai message, but has 100 addresses on the To: line

 

 public void doMail() {
        // Load the Profiles we want to compare against.
        Profile ConsultantProfile = [select id from profile where name='Consultant User'];
        Profile ProjectManagerProfile = [select id from profile where name='Project Manager'];

        // A place to hold the e-mail addresses we're accumulating
        List<String> emailAddresses = new List<String>();

        // A place to hold the Users we're going to check
        List<User> users = new List<User>([SELECT id,ProfileId,FirstName,Email,Total_hours_of_week__c FROM User WHERE User.Total_hours_of_week__c <: 40.00 limit 1000]);
         
        // A place to hold the Users we're going to update.  (Can't just use 'users' because we won't update all of them, only the ones with the right profiles)
        List<User> usersToUpdate = new List<User>();

        // Loop through the users we want to send messages to.
        for (User u: users) {
             system.debug('u is :: ' + u);

             // If the user isn't a Consultant or Project Manager, Skip them.
             if (u.ProfileId != ProjectManagerProfile.id && u.ProfileId != ConsultantProfile.id) continue;

             emailAddresses.add(u.Email);

             // Reset their hours
             u.Total_hours_of_week__c = 0.0;
             usersToUpdate.add(u);
         }
          
         if (emailAddress.isEmpty()) return;  // Nothing to do.

         // Build a message for the email.
         Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
         mail.setToAddresses(emailAddresses);
         mail.setsubject('Less Than 40 Hours for Last Week.');
         mail.setHtmlBody('You have less than 40 hours entered in Salesforce.com for last week.  Please update your hours or enter PTO.  If you have questions or are unable to enter your hours, please contact your System Administrator.');

         Messaging.sendEmail(new Messaging.Email[] {mail});   // Send the one message, but the To: list would have lots of e-mail addresses.
         // Note that setToAddresses is limited to 100 addresses.
         // Note that you might want to use CC or BCC, but those are limited to 25 addresses.
         
         update usersToUpdate;
        }
}

 

or this which just changes that one line.  This might be the better approach.  

 

 

global class NotificationScheduledFor40Hours implements Schedulable {
   
  global void execute(SchedulableContext ctx) {
      doMail();
  }
 
  public void doMail() {
        // Load the Profiles we want to compare against.
        Profile ConsultantProfile = [select id from profile where name='Consultant User'];
        Profile ProjectManagerProfile = [select id from profile where name='Project Manager'];

        // A place to hold the messages we're going to send
        List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();

        // A place to hold the Users we're going to check
        List<User> users = new List<User>([SELECT id,ProfileId,FirstName,Email,Total_hours_of_week__c FROM User WHERE User.Total_hours_of_week__c <: 40.00 limit 1000]);
         
        // A place to hold the Users we're going to update.  (Can't just use 'users' because we won't update all of them, only the ones with the right profiles)
        List<User> usersToUpdate = new List<User>();

        // Loop through the users we want to send messages to.
        for (User u: users) {
             system.debug('u is :: ' + u);

             // If the user isn't a Consultant or Project Manager, Skip them.
             if (u.ProfileId != ProjectManagerProfile.id && u.ProfileId != ConsultantProfile.id) continue;

             // Reset their hours
             u.Total_hours_of_week__c = 0.0;
             usersToUpdate.add(u);

             // Build a message for that user.
             Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

// Change this:
//             mail.setToAddresses(u.Email);
// to this:
             mail.setToAddresses(new String[]{u.Email});


             mail.setsubject('Less Than 40 Hours for Last Week.');
             mail.setHtmlBody('You have less than 40 hours entered in Salesforce.com for last week.  Please update your hours or enter PTO.  If you have questions or are unable to enter your hours, please contact your System Administrator.');
            
             // Add it to the list of emails to send.
             emails.add(mail);
        }

        // If we have messages to send, send them and update the users.
        if (!emails.isEmpty()) {
             Messaging.sendEmail(emails);
             update usersToUpdate;
        }
}

 

Best, Steve;