- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写了一个接口(interface)来包装 Windows Threadpool API,其中许多函数返回普通的 Pointer
类型。
现在我正在编写测试并想使用 delphi-mocks framework模拟该包装器接口(interface)。
问题是 TMock
设置接口(interface)需要一个 TValue
对象来指定模拟函数的默认返回值,我看不到如何做的方法正确地从可用的 TValue
功能。尽管我已经看到 ekPointer
是有效的 TTypeKind
值。
当调用模拟函数时,我从相应的 RTTI 调用中收到 EInvalidCast
异常。
当 RTTI 调用尝试从隐式 TValue
对象转换返回类型值时,就会发生这种情况。
我的代码大致如下1:
type
PTP_POOL = Pointer;
PTP_CLEANUP_GROUP = Pointer;
IThreadPoolApi = interface(IInterface)
{...}
function CreateThreadPool() : PTP_POOL;
function CreateThreadpoolCleanupGroup() : PTP_CLEANUP_GROUP;
{...}
end;
被测类
type
TThreadPool = class(TInterfacedObject, IThreadPool)
FTPApi : IThreadPoolApi;
FPTPPool : PTP_POOL;
FPTPCleanupGroup : PTP_CLEANUP_GROUP;
{...}
public
constructor Create(iapi : IThreadPoolApi);
end;
implementation
constructor TThreadPool.Create(iapi : IThreadPoolApi);
begin
inherited Create();
FTPApi := iapi;
{**** Here I get a EInvalidCast exception when mocking the interface ****}
FPTPPool := FTPApi.CreateThreadPool();
if(not assigned(FPTPPool)) then
begin
{Raise exception}
raise EThreadPoolError('Cannot create TP thread pool');
end;
{**** This case should be tested ****}
FPTPCleanupGroup := FTPApi.CreateThreadpoolCleanupGroup();
if(not assigned(FPTPPool)) then
begin
{Raise exception}
raise EThreadPoolError('Cannot create TP cleanup group');
end;
{...}
end;
以及测试内容
procedure ThreadPoolTest.TestFail_CreateThreadpoolCleanupGroup();
var
apiMock : TMock<IThreadPoolApi>;
testproc : TTestLocalMethod;
begin
apiMock := TMock<IThreadPoolApi>Create();
{**** Needed to reach the call of CreateThreadpoolCleanupGroup
but EInvalidCast is raised ****}
apiMock.Setup.WillReturnDefault('CreateThreadPool',PTP_POOL($FFFFFFFF));
{**** The case to be tested ****}
apiMock.Setup.WillExecute('CreateThreadpoolCleanupGroup',
function (const args : TArray<TValue>; const ReturnType : TRttiType)
: TValue
begin
result := nil;
end);
testproc :=
procedure()
var
threadpool : IThreadPool;
begin
threadpool := TThreadPool.Create(apiMock);
end;
DUnitX.Assert.WillRaise(testproc,EThreadPoolError,
'Cannot create TP cleanup group');
end;
TL;DR;
所以问题是:
我需要做什么才能正确创建 TValue
以包含 PTP_POOL
指针类型?
1)设置MCVE的代码有点太多了。 ,所以我只是在这里简单介绍一下背景,请参阅 {**** 突出显示的注释 ****}
最佳答案
将原始指针分配给 TValue
时,使用 TValue.From<T>()
方法,例如:
TValue.From<PTP_POOL>(nil);
或者,如果您想返回文字值:
TValue.From<PTP_POOL>(PTP_POOL(value));
TValue
没有原始指针的隐式转换,但它确实有 TObject
的隐式转换。和TClass
指针。
如果将无类型 nil 指针直接分配给 TValue
,它调用 TValue.Implicit(TObject)
,这将返回 TValue.Empty
传递 nil 指针时的属性。
如果您分配一个类型化的非 TObject
直接指向 TValue
,它调用 TValue.Implicit(TClass)
,返回 TValue.Empty
如果指针为零,否则返回 TValue
类型 TClass
与指针的值,即使它实际上没有指向有效的类类型。
如果您将指针传递给 TValue.From<T>()
,它返回 TValue
类型 T
与指针的值,即使它是零。
这种差异很微妙,但非常重要。
关于delphi - EInvalidCast 与模拟函数返回指针类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46433385/
我正在尝试调用通过 RTTI 获取的构造函数(运行 D2010 版本 14.0.3593.25826)。构造函数采用字符串和对象的混合作为其参数,所有这些都应初始化为 '' 或 nil。 (免责声明:
我编写了一个接口(interface)来包装 Windows Threadpool API,其中许多函数返回普通的 Pointer 类型。 现在我正在编写测试并想使用 delphi-mocks fra
我正在尝试使用TRttiProperty.SetValue过程通过rtti分配一个对象过程类型的属性,但是当我尝试制作时会引发此异常赋值EInvalidCast:无效的类类型转换 此示例应用程序显示了
我是一名优秀的程序员,十分优秀!