gpt4 book ai didi

c++ - HippoMocks - 在 C++ 中模拟 COM 接口(interface)?

转载 作者:行者123 更新时间:2023-11-30 04:20:26 32 4
gpt4 key购买 nike

The latest version of Hippo Mocks (在其 Git 存储库中)看起来已经添加了对 COM 接口(interface)的支持。我试过模拟一个 ADO 连接对象;这需要对 Hippo Mocks 进行一些调整才能正确构建(似乎代码的 COM 版本未针对其余 Hippo Mocks 的更改进行更新)。我现在正在构建它,但以下测试失败了:

MockRepository mocks;
auto pConn = mocks.Mock<ADONS::_Connection>();
mocks.OnCall(pConn, ADONS::_Connection::AddRef).Return(1);

ADONS::_ConnectionPtr conn = pConn;

智能指针做的第一件事是 AddRef 接口(interface)。我的 mock 不应该关心引用计数,所以我添加了一个只返回 1 的调用期望。但是,一旦 AddRef 被调用,就会抛出一个 HippoMocks::NotImplementedException

有没有人成功地使用 Hippo Mocks 模拟 COM 接口(interface)?

最佳答案

我遇到了同样的问题并解决了。hippomocks 的实际版本现已发布在 github 上:

https://github.com/dascandy/hippomocks

非常感谢提供的链接,这有助于找到修复的想法。

更新,关于我的实现和添加的 COM 支持的详细信息。

首先我让它工作,下面的测试证明了这一点

class ICom 
{
public:
virtual ~ICom() {}
virtual long __stdcall A(void) = 0;
virtual long __stdcall B(int) = 0;
virtual long __stdcall C(int, int) = 0;
...
};


TEST(checkStdCallBase)
{
MockRepository mocks;

ICom* ic = mocks.Mock<ICom>();
mocks.ExpectCall(ic, ICom::A)
.Return(1);

long actual = ic->A();
EQUALS(1, actual);
}

为了让它工作,我不得不修补 hippomocks.h 中的几个地方,这是 virtual_function_index 方法中最重要的地方。更正确保接口(interface)上调用的地址计算正确。

其次,我为 COM 对象添加了一些常见的设置助手,为 AddRef、Release 和 QueryInterface 提供标准行为。

测试展示了如何使用它:

MIDL_INTERFACE("4745C05E-23E6-4c6d-B9F2-E483359A8B89")
COMInterface1 : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE getTObjectCount(
/* [out] */ unsigned long *pCount) = 0;
};

typedef GUID ESTypeID;

MIDL_INTERFACE("356D44D9-980A-4149-A586-C5CB8B191437")
COMInterface2 : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE getMappablePackages(
/* [out] */ long *pSize,
/* [size_is][size_is][out] */ ESTypeID **pIdList) = 0;
};

TEST(CheckThat_AddCommExpectations_Stubs_QueryInterface_AddRef_Release)
{
MockRepository mocks;
COMInterface1* deviceMock = mocks.Mock<COMInterface1>();

AddComExpectations(mocks, deviceMock);

{
CComPtr<IUnknown> pUnk = deviceMock;
CComQIPtr<COMInterface1> pDevice = pUnk;

CHECK(pDevice == pUnk);

IUnknown* p = NULL;
pDevice->QueryInterface(__uuidof(IUnknown), (void**)&p);

CHECK(p == deviceMock);
}
}

TEST(CheckThat_ConnectComInterfaces_Stubs_QueryInterface_ToEachOther)
{
MockRepository mocks;
COMInterface1* deviceMock = mocks.Mock<COMInterface1>();
COMInterface2* devMappingMock = mocks.Mock<COMInterface2>();

ConnectComInterfaces(mocks, deviceMock, devMappingMock);

{
//Com objects can reach each other
CComQIPtr<COMInterface2> pDevMapping = deviceMock;

CHECK(pDevMapping != NULL);
CHECK(pDevMapping == devMappingMock);

CComQIPtr<COMInterface1> pDevNavigate = devMappingMock;

CHECK(pDevNavigate != NULL);
CHECK(pDevNavigate == deviceMock);
}

}

辅助方法 AddComExpectations 和 ConnectComInterfaces 在单独的头文件“comsupport.h”中提供。 header 是 Hippomocks 的附加组件:

template <typename T>
void AddComExpectations(HM_NS MockRepository& mocks, T* m)
{
mocks.OnCall(m, T::AddRef)
.Return(1);
mocks.OnCall(m, T::Release)
.Return(1);
mocks.OnCall(m, T::QueryInterface)
.With(__uuidof(T), Out((void**)m))
.Return(S_OK);

mocks.OnCall(m, T::QueryInterface)
.With(__uuidof(IUnknown), Out((void**)m))
.Return(S_OK);

}

template <typename T1, typename T2>
void ConnectComInterfaces(HM_NS MockRepository& mocks, T1* m1, T2* m2)
{
//from T1 to T2
mocks.OnCall(m1, T1::QueryInterface)
.With(__uuidof(T2), Out((void**)m2))
.Return(S_OK);
//from T2 to T1
mocks.OnCall(m2, T2::QueryInterface)
.With(__uuidof(T1), Out((void**)m1))
.Return(S_OK);

AddComExpectations(mocks, m1);
AddComExpectations(mocks, m2);

//no support for interface hierarchies
//no Base IUnknown -> do it yourself if you really need that special case
}

关于c++ - HippoMocks - 在 C++ 中模拟 COM 接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15298578/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com