Simon
Simon

Reputation: 79

no matching constructor for initialization of a Mock Factory

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>(&parameterMock_, 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

Answers (1)

Simon
Simon

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

Related Questions