Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access Violation When First Matcher is Not Defined #150

Open
IgorKaplya opened this issue Jan 15, 2025 · 1 comment
Open

Access Violation When First Matcher is Not Defined #150

IgorKaplya opened this issue Jan 15, 2025 · 1 comment

Comments

@IgorKaplya
Copy link

An access violation occurs in the TBehavior.Match function when the first matcher is not defined. This issue arises because the MatchWithMatchers function attempts to access an undefined matcher, leading to a runtime error.

Steps to Reproduce:

  1. Create a mock object using TMock<IInterfaceToTest>.
  2. Set up the mock to return a value when specific parameters are matched.
  3. Call the method with the specified parameters.

Example Code:

procedure TExample_MatchersTests.Match_parameter_partial();
var
  mockCredit: TMock<IInterfaceToTest>;
begin
  mockCredit := TMock<IInterfaceToTest>.Create;

  mockCredit.Setup.WillReturn(6).When.TakesTwoParams(1, It(1).IsEqualTo<boolean>(true));

  Assert.AreEqual(6, mockCredit.Instance.TakesTwoParams(1, true));
end;

Presumed Bug Location:
The bug is likely in the TBehavior.Match function, specifically within the MatchWithMatchers function:

function TBehavior.Match(const Args: TArray<TValue>): Boolean;

  function MatchWithMatchers: Boolean;
  var
    i : integer;
  begin
    result := False;
    for i := 0 to High(FMatchers) do
    begin
      // Access violation when FMatchers[i] is nil
      if not FMatchers[i].Match(Args[i+1]) then
        exit;
    end;
    result := True;
  end;
image

Expected Behavior:
The function should handle cases where matchers are not defined without causing an access violation.

Actual Behavior:
An access violation occurs when the first matcher is not defined.

Environment:

  • Delphi version: 11.3
  • Operating System: Windows11
@IgorKaplya
Copy link
Author

I beg your pardon for the hustle :)
This issue is a coincidence caused by an incorrect guard exception in the TProxy<T>.DoInvoke method:

procedure TProxy<T>.DoInvoke(Method: TRttiMethod; const Args: TArray<TValue>; out Result: TValue);
...
// Ooops... Someone just defined only the last arguments matcher, others are nils.
if Length(matchers) > 0 then
  if Length(matchers) < Length(Args) - 1 then
    raise EMockSetupException.Create('Setup called with Matchers but on all parameters : ' + Method.Name); // should say NOT on all parameters

I would suggest

  • either to fix the Guard,
  • or make this awesome tool better and allow people to match only some arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant