Тестирование планируемого класса, выполняющего пакетную вершину, дает противоречивые результаты
@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;
}
}
}
Класс schedulable просто выполняет вершину пакета в методе execute.
По какой-то причине утверждение testInterfaceScheduler НЕ ВЫПОЛНЯЕТСЯ, в то время как testInterfaceBatch ПРОХОДИТ утверждение. Я не могу понять почему, любая помощь приветствуется.
Спасибо!
Ответы
Причина этого в том, что testInterfaceScheduler
вы пытаетесь выполнить две асинхронные транзакции послеTest.stoptest()
- Планируемый
- Batchable
Test.stopTest () выполняет только первую асинхронную транзакцию перед тем, как перейти к оператору assert. В вашем журнале отладки будет показано, что batchable выполняется, но на самом деле это происходит (в контексте тестирования) после утверждения.
Теперь способ исправить это - провести надлежащее модульное тестирование.
- когда вы тестируете расписание; вам просто нужно протестировать его конструктор и метод execute (). Что вас действительно волнует, так это то, что execute () запустил batchable. И вы можете просто убедиться, что для batchable есть AsyncApexJob. Вам не нужно проверять, запускается ли batchable.
- когда вы тестируете batchable, вы предоставляете имитирующие объекты для
start()
поиска, затем проверяетеexecute()
иfinish()
делаете то, что хотите
Если вы передаете аргументы конструктора в batchable, вы можете проверить, что batchable вызывается с правильными аргументами, выполнив:
@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);
}
То есть, вы добавляете зависимости в schedulable некоторые аргументы, которые хотите передать в batchable. Это означает, что у вас будет конструктор без аргументов и конструктор с аргументами для вашего расписания.