Reputation: 79
I am trying for a while now to Unit-test my Factory with gmock/gtest, but I can't get my test to actually use the mock-object I want to test and at this point I feel like I'm doing something fundamentally wrong.
I have the following architecture (headers excluded) with a Factory and ObjectFactory:
class IObject
{
public:
virtual ~IObject() {};
virtual void objectFunction(int someValue) = 0;
};
using ObjectPtr = std::unique_ptr<IObject>;
class IObjectFactory
{
public:
virtual ~IObjectFactory() {};
virtual std::unique_ptr<IObject> create() = 0;
};
using ObjectFactoryPtr = std::unique_ptr<IObjectFactory>;
The ObjectFactory Class returns an instance of the Object Class like this:
ObjectFactory.h
class ObjectFactory : public IObjectFactory
{
public:
ObjectFactory() {};
~ObjectFactory() override {};
std::unique_ptr<IObject> create() override
{
return std::make_unique<Object>();
}
};
I also have the Collection Class
ICollection.h
class ICollection
{
public:
virtual ~ICollection() {};
virtual void someFunction(int value) = 0;
};
Collection.h
class Collection : public ICollection
{
public:
Collection(IParameter *parameter, double& slider, FilterFactoryPtr&& filterFactory);
~Collection() override;
private:
ObjectFactoryPtr objectFactory_ {};
ObjectPtr object_ {};
The Collection Class gets the ObjectFactory injected in it's constructor and creates an instance of Object with it in the constructor like this:
Collection.cpp
Collection::Collection(IParameter *parameter, double aValue, ObjectFactoryPtr&& objectFactory)
: objectFactory (std::move(objectFactory))
{
object_ = objectFactory->create();
}
finally, in a function call of the Collection Class, objectFunction from the Object Class is called.
In order to test the behavior of Object, ObjectFactory and Collection I wrote some mocks like this:
ObjectMock.h
class ObjectMock : public IMock
{
public:
virtual ~ObjectMock() {}
MOCK_METHOD1(objectFunction, void(int someValue));
};
ObjectFactoryMock.h
class ObjectFactoryMock : public IObjectFactory
{
public:
virtual ~ObjectFactoryMock() {}
virtual std::unique_ptr<IObject> create()
{
return std::unique_ptr<dearvrDir::IObject>(createProxy());
}
MOCK_METHOD0(createProxy, IObject* ());
}
ParameterMock.h
class ParameterMock : public IParameterMock
{
public:
virtual ~ParameterMock() {}
MOCK_CONST_METHOD0(getValue, double());
}
finally, I want run the following test to validate the create() call of the objectFactory object:
class UnitTest_CollectionTestCase : public ::testing::Test
{
protected:
std::unique_ptr<Collection> collection_;
ParameterMock parameterMock_;
};
TEST_F(UnitTest_CollectionTestCase, calls_create_on_factory)
{
double value = 123;
collection_ = std::make_unique<Collection>(¶meterMock_, value, std::make_unique<ObjectFactoryMock>());
auto&& objectFactoryMock = std::make_unique<NiceMock<ObjectFactoryMock>>();
ON_CALL(*objectFactoryMock, create())
.WillByDefault(Return(std::make_unique<Object>));
}
However, instead of test results, I get the following error, hinting towards my Return expectation:
error: no matching function for call to 'ImplicitCast_' value_(ImplicitCast_(value_before_cast_)) {} ^~~~~~~~~~~~~~~~~~~~~ note: in instantiation of member function 'testing::internal::ReturnAction > (*)()>::Impl, std::__1::default_delete > (*)(), IObject *()>::Impl' requested here return Action(new Impl(value_)); ^ note: in instantiation of function template specialization 'testing::internal::ReturnAction > (*)()>::operator Action' requested here .WillByDefault(Return(std::make_unique));
I'm kind of hopeless at this point and would be happy to hear any suggestions on the topic.
thanks in advance, Simon
Upvotes: 1
Views: 852
Reputation: 79
Turns out I just had to add "ByMove" to my ON_CALL statement, to instruct my mock object not to invoke the copy constructor, which is deleted due to the unique_ptr.
Thus, the statement
ON_CALL(*objectFactoryMock, create())
.WillByDefault(Return(std::make_unique<Object>()));
has to be
ON_CALL(*objectFactoryMock, create())
.WillByDefault(Return(ByMove((std::make_unique<Object>())));
Upvotes: 1