I have batch job class which fetches ServiceAppointment where Owner.Name = 'System User' in it's Database.QueryLocator start method.

global class CancelDuplicateSaBatchClass implements Database.Batchable<SObject> {
    global Database.QueryLocator start(Database.BatchableContext BC){
        String query = 'SELECT Id,Status FROM serviceappointment WHERE Owner.Name = \'System User\' AND Status = \'None\' ' +
            'AND work_order__r.maintenancePlanId != null';
        return Database.getQueryLocator(query);               
    global void execute(Database.BatchableContext BC,List<ServiceAppointment> duplicateSaList){
        List<ServiceAppointment> duplicateSa = new List<ServiceAppointment>(); 
        for(ServiceAppointment sa :duplicateSaList)
            sa.Status = 'Canceled';
        update duplicateSa;       
    global void finish(Database.BatchableContext BC){


I have created test data for ServiceAppointment and Work Order for my test class CancelDuplicateSaBatchClassTest . But I am not sure how to create ServiceAppointment record whose owner is System User in my test class. That's why probably my SOQL query gives empty records and execute method of my main class does not get executed from my test method. So I am not able to get code coverage for my batch class's execute method. Can someone help me out how to achieve code coverage for this ? I have tried creating a user and assigning it's ID to ownerId of ServiceAppointment object before inserting it. Here is my test class

public class CancelDuplicateSaBatchClassTest {
    @testsetup static void createData(){
        user ServiceTech = UserTestUtils.createTestSysAdminUser('SysUser');
        ServiceTech.FirstName ='System';
        ServiceTech.LastName  ='User';
        List<user> userlist = new list<user>{ServiceTech};
        //Create Operating Hours
        OperatingHours oh  = TestObjectFactory.CreateOperatingHours('Test OH');
        oh.Global__c = true;
        insert oh;
        //Create Service Territory
        ServiceTerritory st  = TestObjectFactory.CreateServiceTerritory('Test Territory For CC',oh.Id,2);
        insert st;
        //Create Account
        Schema.Account acc =  TestObjectFactory.CreateAccount('TestAccount');
        acc.Service_Territory__c = st.Id;
        insert acc;
        //create worktype
        Schema.WorkType wt = TestObjectFactory.CreateNewWorkType('Preventative Maintenance');
        insert wt; 
        //Create test Contact
        Contact testCont = TestObjectFactory.CreateContact('testService', 'cont',  acc.Id);
        insert testCont;
        Case newCase = new Case();
        newCase.AccountId = acc.Id;
        newCase.ContactId = testCont.Id;
        newCase.Function__c = 'Service';
        newCase.Service_Category__c = 'Scheduled Work';
        insert newCase;     
        //Create MaintenancePlan for the Account
        Schema.MaintenancePlan mp = TestObjectFactory.CreateMaintenancePlan(acc.Id,wt.Id,null,null);
        insert mp;   
        //Create Work Order
        schema.WorkOrder wo = TestObjectFactory.CreateNewWorkOrder();
        wo.WorkTypeId = wt.Id;
        wo.MaintenancePlanId = mp.Id;
        wo.SuggestedMaintenanceDate = System.today();
        //wo.CaseId = newCase.Id;
        insert wo;
        //Create Service Appointment 
        schema.ServiceAppointment sa = TestObjectFactory.CreateNewServiceAppointment(wo.id);
        sa.OwnerId = userlist[0].Id;
        sa.Case__c= newCase.Id;
        insert sa;
    static void testBatch(){
        //User[] usr = [Select Id,Name from User where Name = 'System User'];
        CancelDuplicateSaBatchClass cancelDupBat = new CancelDuplicateSaBatchClass(); 
    static void testSchedule(){
        ScheduleCancelDuplicateSaBatchJob schedCancelDuplicate = new ScheduleCancelDuplicateSaBatchJob(); 
        String jobId = System.schedule('Test Cancel Duplicate SA', '20 30 8 10 2 ?', schedCancelDuplicate);

Here is the code coverage result enter image description here

1 Answer 1


Are you sure userlist[0].Id is not null?

After you insert the User record you must make sure to query the record and store its Id (maybe have the UserTestUtils.insertUsers(userlist) method return the list of user records with its Id's) before assigning the OwnerId.

  • Yes, user id is not null. It is valid ID.
    – Ravi
    Jan 17, 2023 at 4:44
  • But it does not have User field.
    – Ravi
    Jan 17, 2023 at 8:51
  • And have you checked the value of the Name field for that user record? Jan 17, 2023 at 17:26

You must log in to answer this question.

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