
Вы написали try catch в своих вспомогательных классах, чтобы зафиксировать ожидаемые ошибки и обработать их? Тогда вы также согласитесь, что обработка исключений — это повторяющийся фрагмент кода, который есть в каждом классе. Это боль в спине, чтобы покрыть в тестовом классе. Это становится кошмаром, если в классе меньше строк, и вы застряли с непокрытыми блоками catch. Итак, сегодня я делюсь подходом, который я попробовал.
Является и имеет
Is a и Has a — это концепции объектно-ориентированного программирования. Есть от наследства, есть от состава.
Я не буду много говорить об этом, но мы собираемся использовать здесь концепцию Is a.
Класс регистратора
В большинстве проектов есть реализация logger. Я собираюсь использовать класс регистратора, который я создал в пользовательских настройках, чтобы включать и выключать ваши журналы. В основном я переместил выполнение кода и попытался поймать в самом классе регистратора. Когда я хочу выполнить какой-либо метод, который может вызвать исключение, я вызываю свой регистратор, чтобы наблюдать за ним и обрабатывать любое исключение, которое может возникнуть.
общедоступный статический объект наблюдения (
Строка имя класса,
Строковое имя метода,
Аргументы Map‹String, Object›
) {
Loggable loggable = (Loggable) Type.forName(className)
.новый экземпляр();
пытаться {
return loggable.call (имя метода, аргументы);
} поймать (исключение кроме) {
Logger logger = новый регистратор (имя класса);
logger.error(exc.getMessage());
возврат отл;
}
}
Метод watch принимает три параметра. Имя класса, имя метода и пара аргументов ключ-значение, которые мне нужно передать в выполнение метода. Я использую класс Type для динамического создания экземпляра класса, который я хочу выполнить. Классы, которые может вызывать регистратор, должны реализовывать интерфейс Loggable. Я расскажу об этом позже в посте. Но в основном у него есть метод вызова, который реализуется классом, который я хочу вызвать.
Пример класса, реализующего Loggable
public с классом совместного использования AccountService реализует Loggable {
общедоступная учетная запись getAccountByAccountNumber (String accountNumber) {
возвращение [
ВЫБЕРИТЕ идентификатор, имя AccountNumber
СО Счета
ГДЕ AccountNumber = :accountNumber
С БЕЗОПАСНОСТЬЮ_ОБЯЗАТЕЛЬНО
];
}
// плохой код (запрос без ограничений и безопасности)
общедоступная учетная запись getAllAccounts () {
return [ВЫБЕРИТЕ Id, AccountNumber Name FROM Account];
}
общедоступный вызов объекта (String methodName, Map‹String, Object› args) {
включить имя_метода {
когда ‘getAccountByAccountNumber’ {
вернуть this.getAccountByAccountNumber(
(Строка) args.get('accountNumber')
);
}
когда ‘getAllAccounts’ {
вернуть this.getAllAccounts();
}
когда еще {
вернуть ноль;
}
}
}
}
В основном, когда имя метода передается в виде строки, я вызываю фактический метод и передаю аргументы из карты именованных аргументов после приведения типов. Идея пришла мне в голову, когда я работал над Queueable, добавляющим себя в очередь для выполнения другой задачи. Я использую ту же концепцию и там, за исключением аргументов.
Если вы, как и я, разработчик JavaScript, вы легко поймете это, поскольку все в JavaScript является объектом.
Наконец, интерфейс Loggable. Loggable — это копия апексного интерфейса Callable, хотя я не наследовал его просто для уверенности, он используется только в контексте логгера.
открытый интерфейс Loggable {
Вызов объекта (строковое действие, Map‹String, Object› argsByName);
}
Теперь, когда у меня все настроено, давайте посмотрим, как вызвать регистратор для просмотра метода.
@IsTest
частный класс AccountService_Test {
@IsTest
статическая пустота getAccountByAccountNumberTest() {
вставьте новую учетную запись (имя = «Тестовая компания»,
AccountNumber = ‘12345’);
Карта‹Строка, Строка› params = новая Карта‹Строка, Строка›();
params.put («номер счета», «12345»);
Тест.начатьТест();
Учетная запись = (Учетная запись) Logger.watch(
«Учетная служба»,
«получить счет по номеру счета»,
параметры
);
Тест.стопТест();
Система.assertNotEquals(
нулевой,
Счет,
«Ожидается, что аккаунт будет возвращен за
указанный номер счета»
);
Система.assertEquals(
‘12345’,
аккаунт.AccountNumber,
«Ожидается, что номер счета будет соответствовать «12345»»
);
}
}
Дайте мне знать, если это было полезно. Поделитесь своими предложениями и комментариями.