Вы написали 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»»

);

}

}

Дайте мне знать, если это было полезно. Поделитесь своими предложениями и комментариями.