德尔福模拟 - 是否可以在使用'WillReturn'模拟的函数中使用'VAR'或'OUT'排列?

Cha*_*iga 5 delphi dunit delphi-xe2 delphi-mocks

我刚开始使用Delphi- Mocks和我的dunit测试,但它几乎没有文档.

问题是:

我正在尝试编写测试 'Test_LogonUser_CheckPwd_GOOD_PASSWORD'

但我不知道如何模拟函数 Fusers.CheckPwd(TEST_USERID,TEST_PASSWORD,ERROR_CODE);

通常我会使用: Fusers.Setup.WillReturn(True).When.CheckPwd(TEST_USERID,TEST_PASSWORD,ERROR_CODE);

但是'ERROR_CODE'是一个OUT值并且给出了编译错误

问题:

  1. 有没有办法让'WillReturn'与OUT或VAR参数一起工作?
  2. 有没有不同的方法来模拟'CheckPwd',以便它看到OUT或VAR参数?

这是我的代码:

/////  TDlUsers
interface
type
{$M+}
  IDlUsers = Interface(IInterface)
 ['{3611B437-888C-4919-B304-238A80DAD476}']
    function   VerifyPassword(UserId: integer; Pwd: string): Boolean;
    function   CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer) : Boolean;
  end;
  function  Dl_Users : IDlUsers;
{$M-}
implementation
type
  TDlUsers = class(TDbIControl,IDlUsers)
  public
    function   VerifyPassword(UserId: integer; Pwd: string): Boolean;
    function   CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer; out ErrorMsg:String) : Boolean;
  end;

  function  Dl_Users : IDlUsers;
  begin
    result :=  TDlUsers.create;
  end;

////  TUserCtrl

interface
uses DlUsers;
type
  TUserCtrl = class
  private
    FUsers      : IDlUsers;
  public
    function    LogonUser_CheckPwd(UserID: Integer; Pwd: String): Boolean;
    function    LogonUser_VerifyPassword(UserID: Integer; Pwd: String): Boolean;
    constructor Create;  overload;
    constructor Create(FUsers : IDlUsers); overload;  { used for Dependency injection }
  end;

implementation

constructor TUserCtrl.Create;
begin
  Create(Dl_Users);
end;
constructor TUserCtrl.Create(FUsers : IDlUsers);
begin
  Self.FUsers          := FUsers;
end;
function TUserCtrl.LogonUser_VerifyPassword(UserID: Integer; Pwd: String): Boolean;
begin
   result := FUsers.VerifyPassword(UserId,Pwd);
end 
function  TUserCtrl.LogonUser_CheckPwd(UserID: Integer; Pwd: String): Boolean;
var ErrorCode : Integer; 
begin
   result := FUsers.CheckPwd(UserID,Pwd,ErrorCode);
   // do what needs to be done with ErrorCode
end;

///// Unit tests


procedure TestTDlUsers.SetUp;
begin
  inherited;
  FUsers    := TMock<IDlUsers>.Create;
  FUserCtrl := TUserCtrl.Create(FUsers);
end;
procedure TestTDlUsers.Test_LogonUser_VerifyPassword_GOOD_PASSWORD;
var Answer : Boolean;
begin
  FUsers.Setup.WillReturnDefault('VerifyPassword',False);
  FUsers.Setup.WillReturn(True).When.VerifyPassword(TEST_USERID,TEST_PASSWORD);
  Answer := FUserCtrl.LogonUser_VerifyPassword(TEST_USERID,TEST_PASSWORD,ErrorCode,ErrorMsg);
  CheckEquals(True,Answer);
end;


procedure TestTDlUsers.Test_LogonUser_CheckPwd_GOOD_PASSWORD;
var Answer : Boolean;
begin
  FUsers.Setup.WillReturnDefault('CheckPwd',False);

  // MAJOR Problem with line  CheckPwd  has an Out pramater 
  FUsers.Setup.WillReturn(True).When.CheckPwd(TEST_USERID,TEST_PASSWORD, ERROR_CODE);


  Answer := FUserCtrl.LogonUser_CheckPwd(TEST_USERID,TEST_PASSWORD,ErrorCode,ErrorMsg);
  CheckEquals(True,Answer);
end;
Run Code Online (Sandbox Code Playgroud)

Arn*_*hez 4

TVirtualInterfaceAFAIK 这是Delphi 模拟所依赖的标准类实现的限制。这是“新 RTTI”的弱点/限制之一。

唯一可能的解决方案是使用不使用此类的存根/模拟库TVirtualInterface

我所知道的唯一拥有自己的“虚拟类”工厂的库是我们的开源mORMot框架(适用于 Delphi 6 到 XE4,在 Win32 和 Win64 下)。它支持varout值参数。要测试任何输出参数值,您可以使用该ExpectsTrace()方法 - 感谢mORMot出色的“调用跟踪”功能