mwilkinson
mwilkinson

Reputation: 97

Delphi Mocks - Verify an overloaded method is never called

As the title suggests, I'm trying to write a test to verify that one version of a method is called, and that the overloaded version is not. Since Delphi-Mocks seems to use indexing on the parameter matching, I'm seeing a fail, and that the the overloaded function is being called when it is in fact, not.

Sample Test Interface

TFoo = class(TObject)
public 
    function Bar(const a, b, c: string) : string; overload;virtual;
    function Bar(const a: string) : string; overload;virtual;
end;

Sample Test Code

procedure TestClass.Test
var mock : TMock<TFoo>;
    bar : TBar;
begin
    mock := TMock<TFoo>.Create;
    bar := TBar.Create(mock);
    mock.Setup.Expect.Once.When.Bar('1','2','3');
    mock.Setup.Expect.Never.When.Bar(It(0).IsAny<string>());        

    //Will Wind up down an if-branch calling either bar(1) or bar(3)
    bar.Execute; 

    mock.VerifyAll;        
end;

Thanks!

Upvotes: 2

Views: 682

Answers (2)

Michael Izvekov
Michael Izvekov

Reputation: 196

You can use "WillExecute" to check this. For example:

procedure TestClass.Test;
var
  mock : TMock<TFoo>;
  bar : TBar;
  CheckPassed: Boolean;
begin
  mock := TMock<TFoo>.Create;
  bar := TBar.Create(mock);

  CheckPassed := True;
  mock.Setup.WillExecute('Bar',
    function(const Args: TArray<TValue>; const ReturnType: TRttiType): TValue
    begin
      if Length(Args) = 2 then // one is for "Self"
        CheckPassed := False;
    end);

  //Will Wind up down an if-branch calling either bar(1) or bar(3)
  bar.Execute;

  Assert(CheckPassed);
end;

Upvotes: 1

Stefan Glienke
Stefan Glienke

Reputation: 21713

FWIW in Spring Mocks (part of the upcoming 1.2 release) the same test would look like this:

procedure TestClass.Test;
var
  mock: Mock<TFoo>;
  bar: TBar;
begin
  foo := TBar.Create(mock);

  bar.Execute; 

  mock.Received(1).Bar('1', '2', '3');
  mock.Received(0).Bar(Arg.IsAny<string>);
end;

As you noticed the concept is a bit different. If you are running with the mock behavior dynamic (which is the default) every call to the mock is allowed and returns the default for functions (like empty string, 0 or nil). Afterwards you can use Received to check if the methods where called the expected times.

Upvotes: 2

Related Questions