首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HippoMocks -在C++中模拟COM接口?

HippoMocks -在C++中模拟COM接口?
EN

Stack Overflow用户
提问于 2013-03-09 00:22:42
回答 1查看 1K关注 0票数 1

The latest version of Hippo Mocks (在其Git库中)似乎增加了对COM接口的支持。我曾尝试模拟一个ADO connection对象;这需要对Hippo Mocks进行一些调整才能正确构建(似乎COM版本的代码没有针对其余Hippo Mocks中的更改进行更新)。我现在构建了它,但是下面的测试失败了:

代码语言:javascript
复制
MockRepository mocks;
auto pConn = mocks.Mock<ADONS::_Connection>();
mocks.OnCall(pConn, ADONS::_Connection::AddRef).Return(1);

ADONS::_ConnectionPtr conn = pConn;

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

有没有人成功地用Hippo Mocks模拟了COM接口?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-10 17:26:36

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

https://github.com/dascandy/hippomocks

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

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

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

代码语言:javascript
复制
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方法中最重要的。更正可确保接口上调用的地址计算正确。

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

测试展示了如何使用它:

代码语言:javascript
复制
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是Hippomock的附加组件:

代码语言:javascript
复制
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
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15298578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档