问问题
841 次
3 回答
4
AFAIK 这是TVirtualInterface
标准类实现的限制,Delphi 模拟所依赖的。这是“新 RTTI”的弱点/限制之一。
唯一可能的解决方案是使用不使用此类的存根/模拟库TVirtualInterface
。
我所知道的唯一拥有自己的“虚拟类”工厂的库是我们的开源mORMot框架(适用于 Delphi 6 到 XE4,在 Win32 和 Win64 下)。它支持var
和out
值参数。要测试任何输出参数值,您可以使用该ExpectsTrace()
方法 - 这要归功于mORMot的出色“呼叫跟踪”功能。
于 2013-08-16T13:40:10.877 回答
4
新的 delphi-mock 可以使用 reference-to-function-WillExecute 来做到这一点:
FUsers.Setup.WillExecute('CheckPwd',
// function CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer; out ErrorMsg: String) : Boolean;
function (const args : TArray<TValue>; const ReturnType : TRttiType) : TValue
var
aErrorCode: Integer;
aErrorMsg: String;
aResult: Boolean
begin
// check against 5, as arg[0] is tkInterface and the method parameters start with arg[1]
Assert.AreEqual(5, Length(args), 'wrong number of arguments passed to IDlUsers.CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer; out ErrorMsg:String) : Boolean');
Assert.IsTrue(args[1].IsType<integer>, 'wrong argument 1 type passed to IDlUsers.CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer; out ErrorMsg:String) : Boolean');
Assert.IsTrue(args[2].IsType<string>, 'wrong argument 2 type passed to IDlUsers.CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer; out ErrorMsg:String) : Boolean');
Assert.IsTrue(args[3].IsType<Integer>, 'wrong argument 3 type passed to IDlUsers.CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer; out ErrorMsg:String) : Boolean');
Assert.IsTrue(args[4].IsType<string>, 'wrong argument 4 type passed to IDlUsers.CheckPwd(UserId: integer; Pwd: string; out ErrorCode: Integer; out ErrorMsg:String) : Boolean');
// ...
arg[3] := TValue.From<Integer>(aErrorCode);
arg[4] := TValue.From<string>(aErrorMsg);
Result := TValue.From<Boolean>(aResult);
end);
(我使用 Delphi XE7 和 DUnitX)
于 2015-09-07T12:15:22.013 回答
2
您使用的库不考虑通过引用传递的参数。它将所有参数视为要在调用模拟时匹配的输入值。此外,在调用模拟函数时,无法为这些参数分配新值。
另一种方法是更改函数的接口以使其可测试。您可以在失败时抛出异常。但是,异常并不适合此功能,因为未能输入正确的用户名和密码并不是异常事件。相反,请考虑返回错误代码。保留一个代码(通常为零)表示成功。
于 2013-08-16T12:20:19.257 回答