Le test d'une classe planifiable exécutant l'apex de lot donne des résultats incohérents
@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;
}
}
}
La classe planifiable exécute simplement l'apex du lot dans la méthode d'exécution.
Pour une raison quelconque, testInterfaceScheduler FAILS assertion, tandis que testInterfaceBatch PASSER l'assertion. Je suis incapable de comprendre pourquoi, toute aide est appréciée.
Merci!
Réponses
La raison en est que testInterfaceScheduler
vous essayez d'exécuter deux transactions asynchrones aprèsTest.stoptest()
- Le programmable
- Le batchable
Test.stopTest () n'exécute que la première transaction asynchrone avant de passer à l'instruction assert. Votre journal de débogage affichera le batch en cours d'exécution, mais cela se produit réellement (dans le contexte du test) après l'assertion.
Maintenant, un moyen de résoudre ce problème est de faire des tests unitaires appropriés
- lorsque vous testez un programme; il vous suffit de tester son constructeur et la méthode execute (). Ce qui vous importe vraiment, c'est que execute () a démarré un batch. Et vous pouvez simplement vérifier qu'il existe un AsyncApexJob pour le batch. Vous n'êtes pas obligé de tester que le batch démarre.
- lorsque vous testez un lot, vous fournissez des objets fictifs
start()
à rechercher, puis vérifiezexecute()
etfinish()
faites ce que vous voulez
Si vous passez des arguments de constructeur au batchable, vous pouvez vérifier que le batchable est appelé avec les arguments appropriés en faisant:
@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
}
où le calendrier execute()
ressemble à ceci
public void execute(SchedulableContext sc) {
InterfaceBatch batchable = new InterfaceBatch(this.args); // from Dependency-injected constructor args
Database.executeBatch(batchable);
}
Autrement dit, votre dépendance injecte dans l'ordonnancable certains arguments que vous souhaitez transmettre au batch. Cela signifie que vous aurez un constructeur no args et un constructeur "with args" pour votre planifiable