1

Hippo Mocks の最新バージョン(Git リポジトリ内) には、COM インターフェイスのサポートが追加されているようです。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、インターフェイスです。私のモックは参照カウントを気にするべきではないので、単純に を返す呼び出し期待値を追加します1AddRefただし、呼び出されるとすぐに aHippoMocks::NotImplementedExceptionがスローされます。

Hippo Mocks を使用して COM インターフェイスをモックすることに成功した人はいますか?

4

1 に答える 1

2

私は同じ問題を抱えていて、それを解決しました。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);
}

これを機能させるために、virtual_function_index メソッドで最も重要な hippomocks.h のいくつかの場所にパッチを適用する必要がありました。修正により、インターフェイスでのコールの正しいアドレス計算が保証されます。

次に、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」で提供されます。ヘッダーは 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
}
于 2015-11-10T09:26:35.513 に答える