I am focusing on writing easy to test code these days and I realize that most of my classes follow the skeleton below:
Some class ObjectManager
needs a DatabaseRepo
, while there is only one type DatabaseRepo
in production (OracleRepo
), I am still implementing it against an interface because I want to be able to mock out the DatabaseRepo
, thus I need to make use of polymorphism. I inject the DatabaseRepo
as a unique_ptr
to the ObjectManager
's constructor, in order to indicate that ObjectManager
owns the DatabaseRepo
.
One thing, for example, which is flawed here is that in the unit test, I access the state of the MockRepo
after I moved it into the ObjectManager
. While its is safe (ObjectManager
) is still alive it looks like a hack.
Question: Using this as a general pattern for the situation where class A
has an object of type B
, are there any design aspects I could improve?
class ObjectManager {
public:
ObjectManager(std::unique_ptr<DatabaseRepo> initRepo) : repo(initRepo) {
}
void process() {
repo->updateRecords();
}
private:
std::unique_ptr<DatabaseRepo> repo;
};
class DatabaseRepo {
public:
virtual void updateRecords = 0;
}
class OracleRepo : public DatabaseRepo {
public:
void updateRecords() overrides {
}
}
class MockRepo : public DatabaseRepo {
public:
void updateRecords() overrides {
}
}
testObjectManager() {
std::unique_ptr<DatabaeRepo> mockrepo =
std::unique_ptr<DatabseRepo>(new MockRepo);
ObjectManager om(std::move(mockrepo));
om.process();
EXPECT_CALLED_ONCE(mockrepo.get()->updateRecords());
}