I have an interface and I want to mock a function of this interface with an argument which is a reference to a function. See code exmple:
unit Main;
interface
procedure Execute;
implementation
uses
Spring.Mocking;
type
TRefFunc = reference to function: Boolean;
IHelper = interface
['{7950E166-1C93-47E4-8575-6B2CCEE05304}']
end;
IIntfToMock = interface
['{8D85A1CD-51E6-4135-B0E9-3E732400BA25}']
function DoSth(const AHelper: IHelper; const ARef: TRefFunc): Boolean;
end;
procedure Execute;
var
IntfMock : Mock<IIntfToMock>;
begin
IntfMock := Mock<IIntfToMock>.Create();
IntfMock.Setup.Returns(True).When.DoSth(Arg.IsAny<IHelper>, Arg.IsAny<TRefFunc>);
end;
end.
Unfortunately I receive a compile error:
[dcc32 Error] Main.pas(29): E2010 incompatible types: 'TRefFunc' and 'Spring.Mocking.Matching.TArg.IsAny<Main.TRefFunc>'
I understand why passing a callback as an argument to a mocked method is not a good idea if the method will be mocked. The best solution is to refactor the code and remove the callback argument from the method. But I was wondering if it is possible to pass an argument, which is a callback, via the Arg.IsAny<T>
syntax?
Thanks and keep healthy
When passing something that is invokable to a function reference parameter the compiler tries to build a closure on it to then pass it to the parameter. This happens also for variables:
var
f: TRefFunc;
begin
f := Arg.IsAny<TRefFunc>; // boom, E2010
This is one of the few cases where Delphi needs the ()
on a call to understand that you actually want to invoke the rhs and assign its result.