Всем привет, заметил одну странность - есть класс:
public class MySample {
public static void sendEmail(){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setTargetObjectId(UserInfo.getUserId());
mail.setTemplateId([SELECT Id FROM EmailTemplate LIMIT 1][0].Id);
mail.setSaveAsActivity(false);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}и юнит тест
private static testMethod void testEmailSending() {
Test.startTest();
Integer emailInvocationsBefore = Limits.getEmailInvocations();
MySample.sendEmail();
System.assert(emailInvocationsBefore != Limits.getEmailInvocations(), 'Email did\'t send');
Test.stopTest();
}Тест проходит успешно.
Теперь попробуем так, есть простой батч:
public class SampleBatch implements Database.Batchable<Object> { public List<Object> start(Database.BatchableContext BC) {
return new List<String>{'test'};
}
public void execute(Database.BatchableContext BC, List<Object> scope) {
MySample.sendEmail();
}
public void finish(Database.BatchableContext BC) {
}
}
и тест к нему
private static testMethod void testEmailSendingFromBatch() {
Test.startTest();
Integer emailInvocationsBefore = Limits.getEmailInvocations();
Database.executeBatch(new SampleBatch());
Test.stopTest();
System.assert(emailInvocationsBefore != Limits.getEmailInvocations(), 'Email did\'t send');
}Данный тест не проходит и в логах везде Number of Email Invocations: 0 out of 10.
В чём подвох?
PS
При большом желании можно протестировать и так:
private static testMethod void testEmailSendingFromBatch2() {
Test.startTest();
Integer emailInvocationsBefore = Limits.getEmailInvocations();
(new SampleBatch()).execute(null, null);
System.assert(emailInvocationsBefore != Limits.getEmailInvocations(), 'Email did\'t send');
Test.stopTest();
}assert
execute точно отрабатывает?
И с какого счастья отработанный батч должен повлиять на контекст вне его выполнения?
Не уверен, что поможет, но может сделать ассерт ДО Test.stopTest();.
Ну а контекстов то получается все равно несколько, и ты смотришь лимиты в двух разных.
Ну так смотри, логика примерно такая:
1) Ты запускаешь отправку емейлов в контексте батча
2) Проверяешь отправлен ли хотя бы один email НЕ(!) в контексте батча.
Даже если бы этот тест прошел, он бы не имел никакого смысла, кроме как запихать assert в тест.
Я это понимаю, теперь вопрос, как протестить отправился email или нет? И почему во всём логе везде Number of Email Invocations: 0 out of 10 (включая лог батча)
а что не так с первым тестом, там ведь нет асинхронного кода
а что не так с первым тестом, там ведь нет асинхронного кода
Потому что там где ты это проверяешь не отправленно ни одного письма.
public void execute(Database.BatchableContext BC, List<Object> scope) {
System.debug(
LoggingLevel.ERROR,
'before Limits.getEmailInvocations() = ' + Limits.getEmailInvocations()
);
MySample.sendEmail();
System.debug(
LoggingLevel.ERROR,
'after Limits.getEmailInvocations() = ' + Limits.getEmailInvocations()
);
}