การทดสอบคลาสที่กำหนดเวลาการรัน batch apex ให้ผลลัพธ์ที่ไม่สอดคล้องกัน

Aug 19 2020
@isTest(seeAllData = false)
private class interfacetest {

    public static testMethod void testInterfaceScheduler(){
        Product2 testproduct = new Product2(Name='test product',ProductCode = '112233');
        insert testproduct;
        Test.startTest();
        InterfaceCalloutMock fakeResponse = new InterfaceCalloutMock(200);
        Test.setMock(HttpCalloutMock.class, fakeResponse);
        InterfaceSchedule InterfaceSc = new InterfaceSchedule();
        String sch = '0 0 23 * * ?';
        system.schedule('Test Interface Scheduler', sch, InterfaceSc);
        Test.stopTest();
        List<Product_Image__c> images = [select Id from Product_Image__c where Product__c =:testproduct.Id];
        system.assertEquals(1, images.size());
    }

    public static testMethod void testInterfaceBatch(){
        Product2 testproduct = new Product2(Name='test product',ProductCode = '112233');
        insert testproduct;
        Test.startTest();
        InterfaceCalloutMock fakeResponse = new InterfaceCalloutMock(200);
        Test.setMock(HttpCalloutMock.class, fakeResponse);
        InterfaceBatch Batchtest = new InterfaceBatch();
        database.executebatch(Batchtest,100);
        Test.stopTest();
        List<Product_Image__c> images = [select Id from Product_Image__c where Product__c =:testproduct.Id];
        system.assertEquals(1, images.size());
    }

    public class InterfaceCalloutMock implements HttpCalloutMock {
        Integer responseCode {get;set;}
        InterfaceCalloutMock(Integer responseCode){
            this.responseCode = responseCode;
        }
        public HTTPResponse respond(HTTPRequest req) {
            HttpResponse resp = new HttpResponse();
            resp.setStatusCode(responseCode);
            resp.setBody('[{"id":"31A3FCE7-DDEF-40D1-8365A8CAA8809348"}]');
            return resp;
        }
    }

} 

คลาสที่กำหนดเวลาได้จะเรียกใช้งาน batch apex ในเมธอด execute

ด้วยเหตุผลบางประการ testInterfaceScheduler FAILS การยืนยันในขณะที่ testInterfaceBatch ผ่านการยืนยัน ฉันไม่สามารถเข้าใจได้ว่าทำไมความช่วยเหลือใด ๆ จึงได้รับการชื่นชม

ขอบคุณ!

คำตอบ

1 cropredy Aug 19 2020 at 18:13

เหตุผลก็คือtestInterfaceSchedulerคุณกำลังพยายามดำเนินการสองธุรกรรมแบบอะซิงโครนัสหลังจากนั้นTest.stoptest()

  • ตาราง
  • แบทช์

Test.stopTest () ดำเนินการเฉพาะธุรกรรม async รายการแรกก่อนดำเนินการต่อในคำสั่ง assert บันทึกการแก้ไขข้อบกพร่องของคุณจะแสดงแบทช์ที่กำลังดำเนินการ แต่เกิดขึ้นจริง (ในบริบททดสอบ) หลังจากการยืนยัน

ตอนนี้วิธีแก้ไขคือทำการทดสอบหน่วยที่เหมาะสม

  • เมื่อคุณทดสอบตารางเวลา คุณต้องทดสอบ constructor และ execute () method สิ่งที่คุณสนใจจริงๆคือ execute () เริ่มแบทเทิลได้ และคุณสามารถตรวจสอบได้ว่ามี AsyncApexJob สำหรับแบทช์ คุณไม่จำเป็นต้องทดสอบว่าแบตสำรองเริ่มต้นได้
  • เมื่อคุณทดสอบแบทชาเบิลให้คุณจัดเตรียมวัตถุจำลองสำหรับการstart()ค้นหาจากนั้นยืนยันexecute()และfinish()ทำในสิ่งที่คุณต้องการ

หากคุณกำลังส่ง constructor args ไปยังแบทชาเบิลคุณสามารถตรวจสอบว่าแบทชาเบิลถูกเรียกด้วย args ที่เหมาะสมโดยทำ:

@IsTest static void testBatchable() {
   InterfaceSchedule schedulable = new InterfaceSchedulable(args);
   Test.startTest();
   schedulable.execute(null);  // SchedulableContext can't be constructed
   Test.stoptest();  // batchable will execute now
   // do asserts

}

โดยที่ Schedulable execute()มีลักษณะเช่นนี้

public void execute(SchedulableContext sc) {
  InterfaceBatch batchable = new InterfaceBatch(this.args);  // from Dependency-injected constructor args  
  Database.executeBatch(batchable);
}    

นั่นคือการพึ่งพาคุณฉีดเข้าไปในอาร์กิวเมนต์ที่กำหนดตารางเวลาที่คุณต้องการส่งผ่านไปยังแบทช์ได้ ซึ่งหมายความว่าคุณจะไม่มีตัวสร้าง args และตัวสร้าง "with args" สำหรับตารางเวลาของคุณ