2013-03-08 81 views
1

The latest version of Hippo Mocks(在它的Git仓库中)看起来增加了对COM接口的支持。我试着嘲笑一个ADO连接对象;其中采取了一些调整Hippo Mocks来正确构建(似乎COM版本的代码没有更新其他Hippo Mocks中的更改)。我现在建立,但下面的测试失败:HippoMocks - 在C++中模拟COM接口?

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

ADONS::_ConnectionPtr conn = pConn; 

智能指针做的第一件事是AddRef接口。我的模拟不应该在意引用计数,所以我添加了一个简单返回1的调用期望值。但是,只要AddRef被调用,就会抛出HippoMocks::NotImplementedException

有没有人成功地用Hippo Mocks嘲笑COM接口?

+0

你能告诉我你需要在com版本中打补丁吗(因为我是打破它的那个人)。如果你提供一个简短的可编译的例子,我会看看。 – Thomas 2013-03-12 10:51:57

+0

@Thomas绝对的,这里有一个补丁文件:https://gist.github.com/bkuhns/5142428如果你有任何问题,请让我知道。我不知道底层内存模型是否足以让COM构建代码变得更进一步。 – 2013-03-12 12:14:06

+0

com的最小单个文件测试用例会很好,因为我从未使用com。 – Thomas 2013-03-12 12:25:38

回答

1

我有同样的问题,并解决它。 hippomocks的实际版本现已发布在GitHub上:

https://github.com/dascandy/hippomocks

的提供的链接,这有助于找到一个固定的想法伟大的赞赏。

UPDATE,有关我的实施和添加的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方法。该更正确保了接口上的呼叫的正确地址计算。

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

试验表明如何使用它:在一个单独的头“comsupport.h”提供

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。标题是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 
} 
+0

请添加摘要或解决方案的详细信息,仅链接答案可能没有用,如果链接将来死亡 – prasun 2015-11-10 09:45:37

+0

答案的工作包括修补hippoMocks框架中的多个位置。 – mrAtari 2015-11-11 13:36:25

+0

关键的想法是在virtual_function_index函数中。 添加了新的情况下: '情况0x0424448b: \t \t \t如果(FUNC [7] == 0×20) \t \t \t \t返回0; \t \t \t返回*(无符号字符*)(功能+ 8)/的sizeof(无效*);' 也有test_com_support_stdcall.cpp提供了一些新的测试和一些helper在ComSupport.h – mrAtari 2015-11-11 13:46:42