0

I'm deploying an apex class and Test class which is covering with 84% in Sandbox however when deploying in Production, its failing and says "Your code coverage is 46%. You need at least 75% coverage to complete this deployment". Note: There are no user records in Production that matches SOQL query in ScheduleInactiveUser `Does it matter?

\\\Batch class

global class ScheduleInactiveUser Implements Schedulable,  Database.Batchable<sObject> {
global void execute(SchedulableContext sc) {
        Database.executeBatch(this, 200); 
         }
global Database.QueryLocator start(Database.BatchableContext BC) {  
        DateTime LoggedInPast2Hours = System.now().addMinutes(-120);
        DateTime LoggedInPast30Mins = System.now().addMinutes(-30);
        string query = 'Select Id, LastLoginDate, IsActive, Name From User Where Profile_Name__c = \'Portal JIT User\' AND LastLoginDate >= :LoggedInPast2Hours AND LastLoginDate <=: LoggedInPast30Mins';
        return Database.getQueryLocator(query);
         }
global void execute(Database.BatchableContext BC, List<sObject> scope) {
        List<User> UserList = (List<User>) scope;
        for(User c : UserList){
         c.IsActive = False;
            } 
        update UserList;
         }
    global void finish(Database.BatchableContext BC) {
         }
}
\\\Test Class
@istest
public class TestScheduleInactiveUser {
    @istest static void ScheduleInactiveUser(){
        
         User u= new User();
        Profile PortalProfileID = [SELECT Id FROM Profile WHERE Name = 'Portal JIT User'];
        u.FirstName= 'TestFirstName';
        u.LastName ='TestLastName';
        u.Email='testuser0@test.org';
        u.username='testuser00@test.com.org';
        u.Alias='Alias';
        u.LocaleSidKey ='en_US';
        u.ProfileId= PortalProfileID.ID;
        u.isActive= FALSE; 
        
        User up= new User();
        Profile PID = [SELECT Id FROM Profile WHERE Name = 'Portal JIT User'];
        up.FirstName= 'TestFirstName';
        up.LastName ='TestLastName';
        up.Email='testuser0@test.org';
        up.username='testuser00@test.com.org';
        up.Alias='Alias';
        up.LocaleSidKey ='en_US';
        up.ProfileId= PID.ID;
        up.isActive= TRUE; 
      
        
      
         Test.startTest();
            ScheduleInactiveUser fc=new ScheduleInactiveUser();
            Database.executeBatch(fc);
        Test.stopTest();
        
    }
}
1

What you want to test is not technically possible with your current design because, as you rightly pointed out, if there are no users in production that match your query then the batch class will return 0 results. Last Login Date is not an editable field so there is no way for you to set it during the test.

You could consider changing the variable scope of your DateTime variables or your query variable and adding @TestVisible to them so that you can modify them in your test class for purposes of testing.

Also as a side note, your query currently queries for both Active and Inactive users. Since your batch only exists to inactivate users, you should add an extra query condition for IsActive = true.

Something like this (note I have not tested this, this is just a rough approximation):

Batch Class

global class ScheduleInactiveUser Implements Schedulable,  Database.Batchable<sObject> {
  @TestVisible
  private DateTime LoggedInPast2Hours = System.now().addMinutes(-120);
  @TestVisible
  private DateTime LoggedInPast30Mins = System.now().addMinutes(-30);

  global void execute(SchedulableContext sc) {
    Database.executeBatch(this, 200); 
  }

  global Database.QueryLocator start(Database.BatchableContext BC) {  
    string query = 'Select Id, LastLoginDate, IsActive, Name From User Where Profile_Name__c = \'Portal JIT User\' AND LastLoginDate >= :LoggedInPast2Hours AND LastLoginDate <=: LoggedInPast30Mins AND IsActive = TRUE';
    return Database.getQueryLocator(query);
  }

  global void execute(Database.BatchableContext BC, List<sObject> scope) {
    List<User> UserList = (List<User>) scope;
    for(User c : UserList){
      c.IsActive = False;
    } 
    update UserList;
  }
  
  global void finish(Database.BatchableContext BC) {
  
  }
}

Test Class

public class TestScheduleInactiveUser {
    @istest static void ScheduleInactiveUser(){
        
         User u= new User();
        Profile PortalProfileID = [SELECT Id FROM Profile WHERE Name = 'Portal JIT User'];
        u.FirstName= 'TestFirstName';
        u.LastName ='TestLastName';
        u.Email='testuser0@test.org';
        u.username='testuser00@test.com.org';
        u.Alias='Alias';
        u.LocaleSidKey ='en_US';
        u.ProfileId= PortalProfileID.ID;
        u.isActive= FALSE; 
        
        User up= new User();
        Profile PID = [SELECT Id FROM Profile WHERE Name = 'Portal JIT User'];
        up.FirstName= 'TestFirstName';
        up.LastName ='TestLastName';
        up.Email='testuser0@test.org';
        up.username='testuser00@test.com.org';
        up.Alias='Alias';
        up.LocaleSidKey ='en_US';
        up.ProfileId= PID.ID;
        up.isActive= TRUE; 
      
        
      
         Test.startTest();
            ScheduleInactiveUser.LoggedInPast2Hours = null;
            ScheduleInactiveUser.LoggedInPast30Mins = null;
            ScheduleInactiveUser fc=new ScheduleInactiveUser();
            Database.executeBatch(fc);
        Test.stopTest();
        
    }
3
  • Cannot access variables in test class ScheduleInactiveUser.LoggedInPast2Hours = null; ScheduleInactiveUser.LoggedInPast30Mins = null; The Variables are at class level in batch apex
    – Saaki
    Mar 9 at 19:13
  • You added @TestVisible to the variables? Mar 9 at 20:13
  • Yes, I added @TestVisible to the variables, I end up creating a user manually in production to match the query. When i rerun the deployment, it worked!! Thanks for all your help
    – Saaki
    Mar 9 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.