Menguji kelas yang dapat dijadwalkan yang menjalankan puncak batch memberikan hasil yang tidak konsisten

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;
        }
    }

} 

Kelas yang dapat dijadwalkan hanya mengeksekusi puncak batch dalam metode eksekusi.

Untuk beberapa alasan testInterfaceScheduler FAILS assertion, sedangkan testInterfaceBatch PASS assertion tersebut. Saya tidak tahu mengapa, bantuan apa pun sangat kami hargai.

Terima kasih!

Jawaban

1 cropredy Aug 19 2020 at 18:13

Alasannya adalah karena testInterfaceSchedulerAnda mencoba menjalankan dua transaksi asinkron setelahnyaTest.stoptest()

  • Dapat dijadwalkan
  • Batchable

Test.stopTest () hanya menjalankan transaksi asinkron pertama sebelum melanjutkan ke pernyataan assert. Log debug Anda akan menampilkan batchable yang dieksekusi tetapi sebenarnya terjadi (dalam konteks pengujian) setelah assert.

Sekarang, cara untuk memperbaikinya adalah dengan melakukan pengujian unit yang tepat

  • saat Anda menguji jadwal; Anda hanya perlu menguji metode konstruktor dan mengeksekusi (). Yang benar-benar Anda pedulikan adalah bahwa execute () memulai batchable. Dan Anda cukup memverifikasi bahwa ada AsyncApexJob untuk batchable. Anda tidak perlu menguji bahwa batchable dimulai.
  • saat Anda menguji batchable, Anda menyediakan objek tiruan untuk start()ditemukan, lalu memverifikasi execute()dan finish()melakukan apa yang Anda inginkan

Jika Anda meneruskan argumen konstruktor ke batchable, Anda dapat memverifikasi bahwa batchable dipanggil dengan argumen yang tepat dengan melakukan:

@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

}

di mana Schedulable execute()terlihat seperti ini

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

Artinya, Anda menyuntikkan ketergantungan ke dalam penjadwalan beberapa argumen yang ingin Anda teruskan ke batchable. Ini berarti Anda akan memiliki konstruktor tanpa args dan konstruktor "with args" untuk penjadwalan Anda