The latest version of Hippo Mocks (in its Git repository) looks to have added support for COM interfaces. I've tried mocking an ADO connection object; which took some tweaking of Hippo Mocks to build properly (seems the COM version of the code wasn't updated for changes in the rest of Hippo Mocks). I have it building now, but the following test fails:
MockRepository mocks;
auto pConn = mocks.Mock<ADONS::_Connection>();
mocks.OnCall(pConn, ADONS::_Connection::AddRef).Return(1);
ADONS::_ConnectionPtr conn = pConn;
The very first thing the smart pointer does is AddRef the interface. My mock shouldn't care about reference counting, so I add a call expectation that simply returns 1. However, as soon as AddRef gets called, a HippoMocks::NotImplementedException gets thrown.
Has anyone had success with mocking a COM interface with Hippo Mocks?
I had the same issue and solved it.
The actual version of hippomocks is now published on github:
https://github.com/dascandy/hippomocks
Great appreciation for the provided links, which helped to find an idea for the fix.
UPDATE, Details about my implementation and the added COM support.
First I made it work, which the following test demonstrates
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);
}
In order to make it work I had to patch several places in hippomocks.h, the most vital in virtual_function_index method. The correction ensures correct address calculation for the call on an interface.
Second, I added some common setup helpers for COM objects, providing standard behaviour for AddRef, Release and QueryInterface.
The tests show how to use it:
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);
}
}
The helper methods AddComExpectations and ConnectComInterfaces are provided in a separate header "comsupport.h". The header is an add-on for 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
}
Related
I am working on a legacy project that makes massive use of ATL COM objects. The task is to extend the unit testing (googletest) by the capability of mocking COM objects, or the smart pointers accessing them. To illustrate, I created a small example project with a single ATL simple object, which only exports the method methodB (part of idl file):
object,
uuid(070a4996-d9cf-4434-a823-3ea9043de394),
dual,
nonextensible,
pointer_default(unique)
]
interface IMyATLObj : IDispatch
{
[id(1)] HRESULT methodB([in] SHORT in, [out, retval] SHORT *out);
};
The objects are accessed using smart pointers of base type _com_ptr_t, such as in this example:
#include <comdef.h>
#include ".../ATLExample_i.h"
_COM_SMARTPTR_TYPEDEF(IMyATLObj, __uuidof(IMyATLObj));
IMyATLObjPtr create() {
IMyATLObjPtr objPtr;
objPtr.CreateInstance(__uuidof(MyATLObj));
return objPtr;
}
void use(IMyATLObjPtr objPtr) {
short val = 0;
objPtr->methodB(1, &val);
std::cout << val << std::endl;
}
Now the question is how I can test the function use(...) without actually creating a COM object. Of course I can create a wrapper class as a facade to all COM interactions that I can mock as usual, e.g.:
class MyObjFacade {
public:
MyObjFacade() {
objPtr.CreateInstance(__uuidof(MyATLObj));
}
virtual short methodB(short in) {
short val;
if (objPtr->methodB(in, &val) == S_OK)
return val;
else
throw;
}
IMyATLObjPtr objPtr;
};
class MYObjMock : public MyObjFacade {
public:
MOCK_METHOD1(methodB, short(short in));
};
void use(MyObjFacade *objPtr) {
short val = 0;
val = objPtr->methodB(1);
std::cout << val << std::endl << std::flush;
}
TEST_F(COMMockTest, Test1) {
MYObjMock mock;
EXPECT_CALL(mock, methodB(_)).WillOnce(Return(43));
use(&mock);
}
But that would obviously leave me with lots of boiler plate code and (possibly) unnessessary changes - this solution would probably not be well adopted. I am looking for an elegant solution that, for example, either introduces a mock object into IMyATLObjPtr mocks the pointer object itself. However, I don't really know where to start because all the available interfaces are generated by ATL and are not easily accessible.
Any ideas?
I am a beginner with google testing framework and have looked up for the solution to this question on SO, but could not find any solutions with respect to C++. Anyway here is what i am trying to do. I have a state machine(service) which is called inside a client code.
//IStateMachine.h
class IStateMachine
{
public:
bool Run(const std::string& action) = 0;
bool IsTxnValid(const std::string& action)= 0;
}
//StateMachine.h
class StateMachine : public IStateMachine
{
bool Run(const std::string& action) override;
bool IsTxnValid(const std::string& action) override;
}
//StateMachine.cpp
bool StateMachine::IsTxnValid(const std::string& action)
{
//Checks whether the given action is valid for the given state.
}
bool StateMachine::Run(const std::string& action)
{
if(IsTxnValid(action)) // #E
{
//Do processing
return true;
}
return false;
}
//Client.h contains a class Client which has function called RunService.
Client
{
public:
void RunService();
std::unique_ptr<IStateMachine> service_; // Initialised to a non null value in either ctr or
// factory.
}
//Client.cpp
bool Client::RunService(std::string&action)
{
if(!service_->Run(action)) //Run in turn calls IsTxnValid().
{
return false;
}
return true;
}
Now i am writing a test case to test the functioning of RunService. I am expecting that if Client::IsTxnValid(param) returns false, then so should RunService.
I have successfully set up the testing recipe and could get the basic tests running. Here is the relevant test i have written. On running this test the i get the error, that IsTransitionValid is never called.
TEST_F(ClientTest, RunService)
{
EXPECT_CALL(*p_service, Run("some_action")); // #A
// EXPECT_CALL(*p_service, Run(testing::_)).WillOnce(::testing::Return(true)); //#B
EXPECT_CALL(*p_service,IsTransitionValid(testing::_)).WillOnce(::testing::Return(false)); //#C : This never gets called.
EXPECT_EQ(false, x_client->RunService());
}
How do i correctly call IsTransitionValid ?
You don't need to set this expectation. I'd go even further: you should not even depend on the implementation of Run in IStateMachine: you should only care about what input it is provided with (parameters, checked with matchers) and what output it can return (so basically only the contract between these two classes) and that's the beauty of it!
It is an implementation detail of StateMachine class (the real implementation) what is done when Run is called. The only thing you need to check in your test is to act upon the result of Run. Using triple A rule (arrange, act, assert): you arrange the test case conditions (using EXPECT_CALLs), then you act (calling RunService) and then you assert (checking the result of RunService).
The technical details:
When you create a mock by inheriting from class Foo:
class Foo {
public:
virtual ~Foo() = default;
virtual void bar() = 0;
}
By defining:
class FooMock : public Foo {
MOCK_METHOD0( bar, void());
}
gmock will add bar (the method to override) and gmock_bar (internal detail of gmock) methods to FooMock class. bar has empty implementation in this case. FooImpl and FooMock share the interface, but have different implementations - hence no call to IsTxnValid is made in Run: the mock class just doesn't know (nor care) how Run is implemented in StateMachine. Remember: in your testcase you interact with StateMachineMock and you only care about the interaction with its public interface, the contract between these two classes and how they cooperate together.
That being said, you of course need to utest the StateMachine class. It may depend on yet another interfaces in its implementations: that will be tested with different set of mocks. But Client should not know about this.
I am new to google test environment. I have a sample code written in C and want to perform unit test with Google test framework.
Below is the sample code
// My module function (test.c)
void Update_user_value(void)
{
int user_value;
user_value = get_val_module(); /* return a integer value*/
if(user_value == 0x1)
update_user_flag(true);
else
update_user_flag(false);
}
// This function is in the other module(stub.c) , so we can use Mock function
void update_user_flag(bool val)
{
struct *temp;
if(val == true)
{
temp->userflag = 1;
}
else
{
temp->userflag = 0;
}
}
I wan to write a test case for the Update_user_value function (only for test.c). Through this function, i am sending some flag value to other module (update_user_flag) to set the flag.
I have written a simple google test like this
TEST_F(sampletest, setuser_flag_true_testcase)
{
//Get value from module
ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x1)); //Mock function
EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function
Update_user_value();
}
TEST_F(sampletest, setuser_flag_false_testcase)
{
//Get value from module
ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x0)); //Mock function
EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function
Update_user_value();
}
My question: Is this test case is enough to validate the Update_user_value function ?
Also i want to know, EXPECT_CALL() is good to use for setting a value to other module ?
If my understanding is wrong, please suggest me a better test case ?
ON_CALL, EXPECT_CALL are macros designed to be used on mock objects. Usually the use case is as follows:
You create an interface to derive from (it will be mocked in your test).
You pass the mock object (to method or via dependency injection).
You make expectations on this object.
See example:
class Foo {
public:
virtual ~Foo() = default;
virtual int bar() = 0;
};
class FooMock : public Foo {
public:
MOCK_METHOD0(bar, int());
};
bool check_bar_over_42(Foo& foo) {
if (foo.bar() > 42) {
return true;
}
return false;
}
TEST(check_bar_over_42_test, bar_below_42) {
FooMock fooMock{};
EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(41));
ASSERT_FALSE(check_bar_over_42(fooMock));
}
TEST(check_bar_over_42_test, bar_above_42) {
FooMock fooMock{};
EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(43));
ASSERT_TRUE(check_bar_over_42(fooMock));
}
AFAIK there is no way of using EXPECT_CALLs on C-like functions. One approach for your problem would be link-time mocking: given a method get_val_module is defined in a separate library, you can create test-only library with get_val_module that will allow you to return the expected values. In tests you would link against test lib, in production - against the real lib.
Let's say I have a streaming API like this:
interface MyInterface {
addListener #0 (listener: Listener) -> (registration: RegisteredListener);
interface Listener {
update #0 () -> stream;
}
interface RegisteredListener {
}
}
I'm having a challenge where the destructor for the server implementation of MyInterface is running before the last registered interface has been released. How can I properly communicate the relationship to cap'n'proto RPC so that even if the client releases it's MyInterface::Client before the RegisteredListener::Client, that either MyInterface::Server lifetime is extended or the RegisteredListener::Server is smart enough to recognize that the original server instance its tracking the registration for is dead. Alternatively, am I misusing the API in some basic way?
Roughly the C++ code looks like this. Server:
class MyInterfaceImpl : public MyInterface {
class Registered final : public MyInterface::RegisteredListener::Server {
public:
Registered(MyInterfaceImpl* parent, uint64_t registrationId) : parent_(parent), id_(registrationId) {}
~Registered() {
parent->unregister(id_);
}
private:
MyInterfaceImpl *parent_;
uint64_t id_;
};
public:
kj::Promise<void> addListener(MyInterface::AddListenerContext context) {
auto registrationId = ++registrationId_;
clients_.emplace_back(context.getParams().getListener());
registrations_.emplace_back(registrationId);
context.getResult().setRegistration(kj::heap<Registered>(this, registrationId));
return kj::READY_NOW;
}
void unregister(uint64_t registrationId) {
auto found = std::find(registrations_.begin(), registrations_.end(), registrationId);
clients_.erase(clients_.begin() + (found - registrations_.begin()));
}
private:
std::vector<MyInterface::Listener::Client> clients_;
std::vector<uint64_t> registrations_;
uint64_t registrationId_ = 0;
};
The client code looks something like this:
capnp::EzRpcClient client("localhost:5923");
MyInterface::Client intf = client.getMain<MyInterface>();
auto& waitScope = client.getWaitScope();
auto listenerRequest = intf.addListenerRequest();
auto listenerPromise = listenerRequest.send();
listenerPromise.wait(waitScope);
{
auto listenerRequest2 = intf.addListenerRequest();
auto listenerPromise2 = listenerRequest2.send();
listenerPromise2.wait(waitScope);
}
Since this is all single-threaded it's pretty easy to spot the use-after-free. I put debug statements in ~MyInterfaceImpl and ~RegisteredListener and the second listener is getting unregistered after ~MyInterfaceImpl. I know that my add listener requests don't have the actual client object but I'm hoping that's not actually an important detail for this.
I recommend having Registered class hold a MyInterface::Client pointing to the parent, in addition to the plain pointer it currently holds.
MyInterfaceImpl *parent_;
MyInterface::Client ownParent_;
uint64_t id_;
This ensures that as long as a Registered still exists, the MyInterfaceImpl won't be destroyed.
Inside the implementation of addListener(), you can obtain a MyInterface::Client pointing to this by calling thisCap().
context.getResult().setRegistration(kj::heap<Registered>(
this, thisCap(), registrationId));
This is the Class design for Device Discovery Library in the network using Bonjour.I need to develop Test case for it using GTest.I am new to GTEst.
Client Program need to implement IDeviceEnumerationCallback to receive Device Information
Callback will be called after Interval time and frequency
Say Interval is 200 ms and frequency is 2. it will call the two times callback after 200 ms.
class IDeviceEnumerationCallback
{
public:
/* This callback is called when Device are Enumerated and is regsitered in EnumerateWiFiDevice method */
virtual void onDeviceDiscovered( DeviceInfo* pDeviceInfo,unsigned short nNoOfDevice,void* pContext) = 0;
};
IDeviceDiscovery
{
virtual int InitialiseDeviceDiscovery(IDeviceEnumerationCallback*) = 0;
virtual void UnInitialiseDeviceDiscovery() = 0;
virtual int EnumerateDevice() = 0;
virtual void SetDiscoveryInterval(unsigned long nDiscoveryInterval);
virtual void SetDiscoveryFrequency(unsigned short nFrequency);
virtual unsigned long GettDiscoveryInterval();
virtual unsigned short GettDiscoveryFrequency();
}
class CDeviceDiscovery : public IDeviceDiscovery
{
// implemenation
}
When I Develop Unit Test for EnumerateDevice() It will return immediately Saying -1 or 1.But the result will be returned in the callback.How to Know Whether Device is enumerated properly or not using GTest.
Do I require GTest Mock Here??
You could use Gmock for this. A good explanation can be found on this page:
http://code.google.com/p/googlemock/wiki/ForDummies
You would mock IDeviceEnumerationCallback
#include <gmock/gmock.h>
class MockIDeviceEnumerationCallback : public IDeviceEnumerationCallback
{
public:
MOCK_METHOD3(onDeviceDiscovered, void(DeviceInfo* pDeviceInfo,unsigned short nNoOfDevice,void* pContext));
};
and expect an call to the function using
MockIDeviceEnumerationCallback mock;
EXPECT_CALL(mock, onDeviceDiscovered(_, _, _))
.WillOnce(Return(1));