Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test if a Procedure Throws an Exception in DUnitX

Tags:

delphi

I am working with the DUnitX framework, and am trying to test if the procedure throws an exception.

Currently I have the following test procedure:

procedure TAlarmDataTest.TestIdThrowsExceptionUnderFlow;
begin
  Input := 0;
  Assert.WillRaise(Data.GetId(input), IdIsZeroException, 'ID uninitialized');
end;

When I go to compile I get an error 'There is no overloaded version of 'WillRaise' that can be called with these arguments.'

Is there a better way to check if the procedure is raising a custom exception, or should I use a try, except block that passes if the exception is caught?

like image 394
TheEndIsNear Avatar asked Mar 27 '14 09:03

TheEndIsNear


1 Answers

The first parameter of WillRaise is TTestLocalMethod. That is declared as:

type
  TTestLocalMethod = reference to procedure;

In other words, you are meant to pass a procedure that WillRaise can call. You are not doing that. You are calling the procedure. Do it like this:

Assert.WillRaise(
  procedure begin Data.GetId(input); end,
  IdIsZeroException, 
  'ID uninitialized'
);

The point being that WillRaise needs to invoke the code that is expected to raise. If you invoke the code then the exception will be raised whilst preparing the parameters to be passed to WillRaise. So, we need to postpone execution of the code that is expected to raise until we are inside WillRaise. Wrapping the code inside an anonymous method is one simple way to achieve that.

For what it is worth, the implementation of WillRaise looks like this:

class procedure Assert.WillRaise(const AMethod : TTestLocalMethod; 
  const exceptionClass : ExceptClass; const msg : string);
begin
  try
    AMethod;
  except
    on E: Exception do
    begin
      CheckExceptionClass(e, exceptionClass);
      Exit;
    end;
  end;
  Fail('Method did not throw any exceptions.' + AddLineBreak(msg), 
    ReturnAddress);
end;

So, WillRaise wraps the call to your procedure in a try/except block, and fails if the desired exception is not raised.

If you are still struggling with understanding this then I suspect you need to brush up your knowledge of anonymous methods. Once you get on top of that I'm sure it will be obvious.

like image 129
David Heffernan Avatar answered Oct 14 '22 22:10

David Heffernan