การทดสอบคลาสที่กำหนดเวลาการรัน batch apex ให้ผลลัพธ์ที่ไม่สอดคล้องกัน
@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 ผ่านการยืนยัน ฉันไม่สามารถเข้าใจได้ว่าทำไมความช่วยเหลือใด ๆ จึงได้รับการชื่นชม
ขอบคุณ!
คำตอบ
เหตุผลก็คือ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" สำหรับตารางเวลาของคุณ