2013-03-08 84 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