CheckException只接受0参数的方法;我怎么测试等方法抛出异常?
-
26-09-2019 - |
题
我不知道什么是最好的实践来检验DUNIT例外。我不是很熟悉的德尔菲法指针。是否有可能以绑定参数的方法指针,以便它可以不带参数调用。目前,我总是写一个做到这一点手动“结合”的另一种方法。这将是烦人如果SUT有很多投掷方法。
// What i did before i knew abput CheckExcepion
procedure MyTest.MyMethod_BadInput_Throws;
var
res: Boolean;
begin
res := false;
try
sut.MyMethod('this is bad');
except
on e : MyExpectedException do:
res := true;
end;
CheckTrue(res);
end;
// What i do now
procedure MyTest.MyMethodWithBadInput;
begin
sut.MyMethod('this is bad');
end;
procedure MyTest.MyMethod_BadInput_Throws;
begin
CheckException(MyMethodWithBadInput, MyExpectedException);
end;
// this would be nice
procedure MyTest.MyMethod_BadInput_Throws;
begin
CheckException(
BindArguments(sut.MyMethod, 'this is bad'), // <-- how to do this
MyExpectedException);
end;
解决方案
您可以使用StartExpectingException
包围你的你的方法调用)。
StartExpectingException(MyException);
MyMethod(MyParam);
StopExpectingException();
其他提示
我不知道是否DUNIT支持它,但是这是一个完美的使用情况进行了其在2010年德尔福推出如果DUNIT不支持它,那么你可以很容易地修改自己的源匿名方法。
如所指出的,这是匿名方法的好地方。
下面是我如何做到这一点。我“借用”这从亚历乔巴努:
procedure TestTMyClass.CheckException(aExceptionType: TClassOfException; aCode: TTestCode; const aMessage: String);
var
WasException: Boolean;
begin
WasException := False;
try
aCode;
except
on E: Exception do
begin
if E is aExceptionType then
begin
WasException := True;
end;
end;
end;
Check(WasException, aMessage);
end;
,然后用类似叫它:
CheckException(ETestingException,
procedure begin FMyClass.RaiseTestingException end,
'The ETestingException exception didn''t get raised. That is impossible!');
要使用StartExpectingException()
是不是如果你想测试一个以上异常情况下的最佳途径。为了有例外测试所有可能的情况下,在我的测试过程中,同时我用这个算法:
uses
Dialogs;
procedure MyTest.MyMethod_Test;
begin
// Test for Exceptions
try
MyMethod(MyParam1CreatingException1);
ShowMessage('Error! There should have been exception: Exxx here!');
Check(false);
except on E: Exception do Check(E is ExceptionType1); end; // This exception is OK
try
MyMethod(MyParam2CreatingException2);
ShowMessage('Error! There should have been exception: Exxx here!');
Check(false);
except on E: Exception do Check(E is ExceptionType2); end; // This exception is OK
// ... test other exceptions ...
// Test other parameters
CheckEquals('result1', MyMethod(MyParam1));
CheckEquals('result2', MyMethod(MyParam2));
// ... other tests ...
end;
为什么我用ShowMessage('Error! There should be exception: Exxx here!');
,而不是提供Check(false, 'There should have been an EListError.');
方法的原因是,在我的情况(的Delphi6)的Check(boolean, 'Message')
不工作 - 它不会在情况显示的信息是检查里面try...except
块(不知道为什么)。
这是尼克Hodges的答案的工作和改进的版本,它的子类DUNIT的TestFramework.TTestCase
:
uses
TestFramework, System.SysUtils;
type
TTestCode = reference to procedure;
TTestCasePlus = class(TestFramework.TTestCase)
procedure CheckException(
ExceptionType: TClass; Code: TTestCode; const Message: String = '');
end;
implementation
procedure TTestCasePlus.CheckException(
ExceptionType: TClass; Code: TTestCode; const Message: String = '');
{ Check whether some code raises a specific exception type.
Adapted from http://stackoverflow.com/a/5615560/797744
Example:
Self.CheckException(EConvertError,
procedure begin UnformatTimestamp('invalidstr') end);
@param ExceptionType: The exception class which we check if it was raised.
@param Code: Code in the form of an anonymous method that should raise the
exception.
@param Message: Output message on check failure. }
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;
一个不错的奖金,以检查是否异常升高超过Start/StopExpectingException()
的这个方法是,你可以运行在调试版本的TestRunner,它会跟不上打扰你“异常升高。休息一下?继续吗?”每当产生一个异常 - 即使它被处理