Can Google Mock a method with a smart pointer return type?
A feasible workaround for google mock framework's problems with non (const) copyable function arguments and retun values is to use proxy mock methods.
Suppose you have the following interface definition (if it's good style to use std::unique_ptr
in this way seems to be more or less a philosophical question, I personally like it to enforce transfer of ownership):
class IFooInterface {
public:
virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) = 0;
virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() = 0;
virtual ~IFooInterface() {}
};
The appropriate mock class could be defined like this:
class FooInterfaceMock
: public IFooInterface {
public:
FooInterfaceMock() {}
virtual ~FooInterfaceMock() {}
virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) {
nonCopyableParamProxy(uPtr.get());
}
virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() {
return std::unique_ptr<IMyObjectThing>(nonCopyableReturnProxy());
}
MOCK_METHOD1(nonCopyableParamProxy,void (IMyObjectThing*));
MOCK_METHOD0(nonCopyableReturnProxy,IMyObjectThing* ());
};
You just need to take care, that configurations (Actions taken) for the nonCopyableReturnProxy()
method return either NULL
or an instance allocated dynamically on the heap.
There's a google-mock user forum thread discussing this topic where one of the maintainers states that the google-mock framework won't be changed to support this in future arguing that their policies strongly discourage the usage std::auto_ptr
parameters. As mentioned this is IMHO a philosophical point of view, and the capabilities of the mocking framework shouldn't steer what kind of interfaces you want to design or you can use from 3rd party APIs.
As said the answer describes a feasible workaround.
I know this post was from a long time ago, so you've probably discovered the answer by now.
gmock previously did not support mock functions that returned any movable type, including smart pointers. However, in April 2017, gmock introduced a new Action modifier ByMove
.
EXPECT_CALL(*foo_, Bar(_, )).WillOnce(Return(ByMove(some_move_only_object)));
where some_move_only_object can be e.g. a std::unique_ptr.
So yes, now gmock can mock a function that takes a smart pointer.
I have recently discovered that returning smart pointers by mocked functions is still not very user friendly. Yes, the new action ByMove
had been introduced, however it turns out it may be used only once during the test. So imagine you have a factory class to test that repeatedly returns unique_ptr
to the newly created object.
Any attempt to .WillRepeatedly(Return(ByMove)
or multiple ON_CALL
with .WillByDefault(Return(ByMove)
will result in the following error:
[ FATAL ] Condition !performed_ failed. A ByMove() action should only be performed once.
This is also clearly stated in the GMock Cookbook in the paragraph "Mocking Methods That Use Move-Only Types".
in the mock class put same as you want
MOCK_METHOD0(Create, std::unique_ptr());
and in the test as below
EXPECT_CALL(<mock-obj>, Create())
.WillOnce([]()->std::unique_ptr<IMyObjectThing>{
return std::make_unique<IMyObjectThing>();
});
if vs 2010 not support for lambda, you can use a functor