sau_73
unread,May 13, 2011, 12:51:54 PM5/13/11Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Google C++ Mocking Framework
ISSUE: Getting a Debug Error when running unit tests in 1.6 where in
1.5 it worked fine.
Error: R6025 - pure virtual call
Background:
First of all, thanks this excellent tool which has revolutionised my C+
+ unit testing!
I've been using gmock for a bout a year now, and sometimes I need to
mock COM interfaces. In 1.5 it worked out fine. I am presently
upgrading to 1.6 and now I'm getting the above error whenever the Mock
COM object is destroyed. In my real code a factory method cocreates a
COM object and assigns it to a CComPtr<>. In my unit test I override
the factory so I can inject a fake COM object.
I have a TestDouble for the COM object installed in my Testable
version of the SUT and pass back the address of that (it gets copied
into a CComPtr<>.
In v1.5 this all worked, fine, but I'm getting the runtime error in
v1.6.
The Release() call made by the CComPtr<> going out of scope for the
last time seems to be passed on to the base class (IFoo interface in
this case) rather than being handled by the TestDouble.
I've tried to debug this, but get a bit lost in the depths of the
gmock code :)
I've put together a sample project that demonstrates the problem - but
I can't see any way to attach it to this post.
Here's the code - shout if you want the full sample...
---------------------------------------------------------
class CSystemUnderTest
{
public:
void DoSomething(){
GetFoo(m_pDoc);
m_pDoc->Lookup();
}
protected:
virtual void GetFoo(CComPtr<IFoo>& pFoo) { // do nothing we're just
testing }
private:
CComPtr<IFoo> m_pDoc;
};
---------------------------------------------------------
Here's the "interface" for the depended upon COM object (you'll need
to include atlcom.h and atlase.h I think..)
---------------------------------------------------------
MIDL_INTERFACE("A5EB27A2-3F8F-44E7-AFAC-762DFE34F4CA")
IFoo : public IDispatch
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Lookup()=0;
};
---------------------------------------------------------
Now here's my testdouble (Mock class):
---------------------------------------------------------
// Use this macro to mock the IUnknown interface
#define MOCK_IUNKNOWN MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE,
AddRef, ULONG()); \
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Release, ULONG()); \
MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, QueryInterface,
HRESULT(const IID&, void**));
// Use this macro to mock the IDispatch interface
#define MOCK_IDISPATCH MOCK_IUNKNOWN \
MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTypeInfoCount,
HRESULT(UINT*)); \
MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTypeInfo,
HRESULT(UINT, LCID, ITypeInfo**)); \
MOCK_METHOD5_WITH_CALLTYPE(STDMETHODCALLTYPE, GetIDsOfNames,
HRESULT(const IID&, LPOLESTR *, UINT, LCID, DISPID*)); \
MOCK_METHOD8_WITH_CALLTYPE(STDMETHODCALLTYPE, Invoke,
HRESULT(DISPID,REFIID,LCID,WORD,
DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*));
class IFoo_TestDouble : public IFoo
{
public:
// move const/dest impl to cpp file for quicker
complile..
IFoo_TestDouble() {
ON_CALL(*this, QueryInterface(_,_))
.WillByDefault(DoAll(SetArgumentPointee<1>((void*)this),
Return(S_OK)));
}
virtual ~IFoo_TestDouble(){}
MOCK_IDISPATCH;
MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Lookup, HRESULT());
};
-----------------------------------------------
Now here's my testable CSystemUnderTest (for injecting fake IFoo)
class Testable_CSystemUnderTest : public CSystemUnderTest
{
public:
Testable_CSystemUnderTest() {}
IFoo_TestDouble& Foo(){return m_Doc;}
protected:
virtual void GetFoo(CComPtr<IFoo>& pFoo)
{
/// Assign the ptr to the testdouble. Faked IUnknown
methods will fake the COM ref counting..
pFoo = (IFoo*)&m_Doc;
}
private:
IFoo_TestDouble m_Doc;
};
--------------------------------------------------
And here's a test that produces the error:
{
Testable_CSystemUnderTest test;
test.DoSomething();
}
<- error occurs when the Testable_CSystemUnderTest goes out of scope..
Like I said, this all worked fine under gmock 1.5, so has something
changed in the internal implementation to make this break?
Thanks for you help.