简体   繁体   English

如何在 DUnitX 和 Spring4D 1.2.2 中使用 var 参数模拟方法调用

[英]How can I mock a method call with var parameter in DUnitX and Spring4D 1.2.2

How can I mock an interface method call like procedure foo( var i_: integer ) .如何模拟接口方法调用,如procedure foo( var i_: integer ) The tested method local variable passed as a var param, so the test must use Arg.IsAny (The test does not access it).测试方法局部变量作为 var 参数传递,因此测试必须使用 Arg.IsAny(测试不访问它)。 The result value is not the same as the out value of the var param, because the tested method does some processing on it before gives back as a result.结果值与 var 参数的 out 值不同,因为被测试的方法在返回结果之前对其进行了一些处理。 The commented When variations in the test does not compile.注释的When测试中的变体无法编译时。 The current one compiles but results an undefined value (mock Executes does not call at all, because the var=pointer values don't match).当前编译但产生一个未定义的值(模拟Executes根本不调用,因为 var=pointer 值不匹配)。 How could I mock a method call with a var parameter?如何模拟带有var参数的方法调用?

unit Unit1;

interface

uses
    DUnitX.TestFramework
  , Spring.Mocking
  ;

type
  IMyInterface = interface ( IInvokable )
    ['{606BA1D8-EAEC-42CB-A774-911628FD2E6C}']
    procedure foo( var x_ : integer );
  end;

  TMyClass = class
    private
      fMyInterface : IMyInterface;
    public
      constructor Create( myInterface_ : IMyInterface );
      function bar : integer;
  end;

  [TestFixture]
  TMyClassUnitTest = class
    public
      [Test]
      procedure bar;
  end;

implementation

constructor TMyClass.Create( myInterface_ : IMyInterface );
begin
  inherited Create;
  fMyInterface := myInterface_;
end;

function TMyClass.bar : integer;
var
  i : integer;
begin
  fMyInterface.foo( i );
  result := i + 1;
end;

procedure TMyClassUnitTest.bar;
var
  myInterfaceMock : Mock<IMyInterface>;
  myClass : TMyClass;
  i : integer;

  procedure prepareMyInterfaceFooCall( fooVarValue_ : integer );
  var
    ii : integer;
  begin
    ii := 7;
    myInterfaceMock.Setup.Executes(

      function ( const args_ : TCallInfo ) : TValue
      begin
        args_[0] := TValue.From<integer>( fooVarValue_ );
      end

    //).When.foo( Arg.IsAny<integer> );
    //).When.foo( integer( Arg.IsAny<integer> ) );
    ).When.foo( ii );
  end;

begin
  prepareMyInterfaceFooCall( 5 );
  myClass := TMyClass.Create( myInterfaceMock );
  try
    i := myClass.bar;
  finally
    FreeAndNIL( myClass );
  end;
  Assert.AreEqual( 6, i );
end;

end.

1.2.2 cannot do this but 2.0 can do (currently develop branch) 1.2.2 不能这样做,但 2.0 可以(目前正在开发分支)

Here is the relevant change to your code:这是您的代码的相关更改:

procedure prepareMyInterfaceFooCall(expectedValue: Integer);
begin
  myInterfaceMock.Setup.Executes
  // put the wildcard matcher because your code passes a non initialized variable
  // a matcher on the When() always has priority over any individual parameter matching
  .When(Args.Any)
  // use the Arg.Ref syntax specifying the return value
  .foo(Arg.Ref<Integer>(expectedValue).Return);
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM