Тестирование исключений является важной частью разработки программного обеспечения, так как позволяет убедиться в корректности работы кода в случае возникновения нештатных ситуаций. В среде Delphi для тестирования часто используется фреймворк DUnit, который позволяет проводить модульное тестирование.
Проблема
Разработчики, работающие с DUnit, могут столкнуться с необходимостью тестирования методов, которые выбрасывают исключения. Однако, стандартный метод CheckException принимает только методы без параметров. Это может привести к необходимости написания дополнительных методов для "связывания" аргументов, что становится неудобным, особенно если система под тестированием (SUT) содержит много методов, выбрасывающих исключения.
Решение
Для оптимизации процесса тестирования исключений в DUnit можно использовать анонимные методы, которые были введены в Delphi 2010. Это позволяет создавать методы без привязки к классу, что удобно для передачи в CheckException без необходимости создания дополнительных вспомогательных методов.
Пример кода
uses
Dialogs, System.SysUtils;
procedure MyTest.TestMyMethod_ThrowsException;
var
WasException: Boolean;
begin
WasException := False;
try
MyMethod('this is bad');
except
on e : MyExpectedException do
WasException := True;
end;
CheckException(WasException, True, 'Expected exception was not thrown.');
// Ожидается, что здесь будет сгенерировано исключение, и выполнение кода после
// инструкции StopExpectingException не произойдет.
end;
procedure TTestCasePlus.CheckException(
ExceptionType: TClass; Code: TTestCode; const Message: String = '');
var
WasRaised: Boolean;
begin
WasRaised := False;
try
Code;
except
on E: Exception do
if E is ExceptionType then
WasRaised := True;
end;
Check(WasRaised, Message);
end;
type
TTestCode = reference to procedure;
Альтернативные способы
Также существует альтернативный подход, использующий методы StartExpectingException и StopExpectingException. Эти методы позволяют указать, что последующий за ними код должен вызвать исключение, и если это не происходит, тест будет считаться неудачным.
StartExpectingException(MyExpectedException);
MyMethod('this is bad');
StopExpectingException();
Однако, если нужно протестировать несколько исключений, использование StartExpectingException может быть не лучшим решением, так как после его вызова дальнейший код не будет выполнен, даже если ожидается возникновение исключений.
Лучшие практики
Для тестирования нескольких случаев с исключениями можно использовать следующий алгоритм:
uses
Dialogs;
procedure MyTest.MyMethod_Test;
begin
// Тестирование исключений
try
MyMethod(MyParam1CreatingException1);
ShowMessage('Error! There should have been exception: Exxx here!');
Check(False);
except
on E: Exception do
Check(E is ExceptionType1); // Это исключение ожидается
end;
try
MyMethod(MyParam2CreatingException2);
ShowMessage('Error! There should have been exception: Exxx here!');
Check(False);
except
on E: Exception do
Check(E is ExceptionType2); // Это исключение также ожидается
end;
// ... тестирование других исключений ...
end;
Заключение
Использование анонимных методов и различных подходов к тестированию исключений в DUnit позволяет оптимизировать процесс тестирования и сделать его более удобным и эффективным, особенно при работе с большим количеством методов, выбрасывающих исключения.
Оптимизация тестирования исключений в фреймворке DUnit в Delphi с использованием указателей на методы для упрощения процесса и увеличения эффективности тестирования методов, выбрасывающих исключения.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS