I'm trying to make extensive tests for my new project but I have a problem.
Basically I want to test MyClass. MyClass makes use of several other class which I don't need/want to do their job for the purpose of the test. So I created mocks (I use gtest and gmock for testing)
But MyClass instantiate everything it needs in it's constructor and release it in the destructor. That's RAII I think.
So I thought, I should create some kind of factory, which creates everything and gives it to MyClass's constructor. That factory could have it's fake for testing purposes. But's thats no longer RAII right?
Then what's the good solution here?
You mock it the same way you'd mock any other class. Have the RAII class' constructor take care of it.
class MyInterface
{
virtual void MyApiFunction(int myArg)
{
::MyApiFunction(myArg);
}
};
class MyRAII : boost::noncopyable //Shouldn't be copying RAII classes, right?
{
MyInterface *api;
public:
MyRAII(MyInterface *method = new MyInterface)
: api(method)
{
//Aquire resource
}
~MyRAII()
{
//Release resource
delete api;
}
};
class MockInterface : public MyInterface
{
MOCK_METHOD1(MyApiFunction, void(int));
};
TEST(Hello, Hello)
{
std::auto_ptr<MockInterface> mock(new MockInterface);
EXPECT_CALL(*mock, ....)...;
MyRAII unitUnderTest(mock.release());
}
Related
I am a bit rusty on my C++, and in particular with references.
I have an old code, something like
TEST(SomeTest,someFunction){
AClass anObject= GetSomeObject();
ASingletonClass &aReference= ASingletonClass::GetInstance();
//... some more code
}
For reasons of design I have to rewrite this code, and this time I have to use an auxiliary class (*)
class ASingletonClassFixture: public testing:Test{
public:
void SetUp() override
{
anObject=GetSomeObject();
aReference= ASingletonClass::GetInstance();
}
protected:
AClass anObject;
ASingletonClass &aReference; //<--I don't think this is correct
}
I think that the above code is not correct because references should be initialized when created.
So my question is how can I do something like this? Can I do it in the constructor?
(*) The reason if you are interested -although not essential to know- is because I am writing a test fixture.
Yes, you can do it in the test constructor - and it is even the recommended way:
class ASingletonClassFixture: public testing::Test{
public:
ASingletonClassFixture() : aReference{ASingletonClass::GetInstance()} {}
void SetUp() override
{
anObject=GetSomeObject();
}
protected:
AClass anObject;
ASingletonClass &aReference; //<--I don't think this is correct
};
see this FAQ.
However, be mindful that even though constructor and SetUp are called before each test body (the order is always ctor, SetUp, test body, TearDown, dtor), given you're using a singleton - it will be initialized only once and it's state will be shared between the test cases! What is more, if you have more test suites in the same test binary, as the singleton is most probably implemented as a static object, it will be initialized once for the whole test binary and deinitialized once the main method of the binary exits.
I have situation in which I am getting a crash on clearing the memories in destructor. Please see the code below
C++ Code:
class Key{
....
};
Class Object {
...
};
Class E {
private:
vector<Object> m_vector;
};
Class A {
public:
virtual void check()=0;
protected:
hashmap<Key*,E*> myMap;
};
A:~A() {
EMapItr eMapItr = myMap.beginRandom();
for(; eMaptr; ++eMapItr) {
delete eMapItr.value();
}
E:~E() {
m_vector.clear();
}
class B: public A {
public:
virtual void check()
private:
DB* db;
}
void B::check() {
db->create(&myMap);
}
QT Code:
class MyQtAction {
public:
void act() ;
private:
GUIObject* guiWindowObject
};
MyQtAction::act() {
A* aobj = new B();
if(!guiWindowObject) {
guiWindowObject = new GUIObject(aobj);
}
};
class GUIObject:public QWidget {
private:
A* guiAobj;
};
GUIObject:GUIObject(A* obj) {
guiAobj= obj;
}
GUIObject:~GUIObject {
}
Now Can you please where shall I delete the point of A class because object of A is created multiple times
Since you're using Qt, I'd suggest your leverage on its very powerful "Object Trees & Ownership" model that comes for free with it:
QObjects organize themselves in object trees. When you create a
QObject with another object as parent, it's added to the parent's
children() list, and is deleted when the parent is.
http://doc.qt.io/qt-5/objecttrees.html
derive your classes from QObject, and make them use/require a QObject as parent parameter.
then, at instanciation, specify the parent object (this is why there
is a "parent" parameter all over the place in Qt's constructors
documentation),
no more delete, enjoy automagic deletion of child, grand child,
grand-grand child etc when the parent is deleted / goes out of scope.
You can use the QObject::dumpObjectTree() to visualise the parent/child tree at run time.
http://doc.qt.io/qt-5/qobject.html#dumpObjectTree
Now, there can be some tricky situations (see the doc above) which may require manual explicit delete, but in my experience 95% of the time it's fine - and in any case much less error prone than handling this yourself as your application grow big and complex. If you use Qt, you definitely want to use this. It's a great feature of the framework.
EDIT:
Now, about the context of your development and "is it C++ or is it Qt"?
If you want to learn C++ the hard and good way (and just add a bit of
fun with a few Qt graphical widgets), then you must understand the
destructors and be able to to handle it by yourself.
On the other hand, if you want to create a serious Qt application,
then you must embrace the Qt framework as a whole, and this
parent/child QObject fundamental base class, from which all others Qt's
class are derived is fundamental and oh-so-useful. There are a couple
of others root fundamental Qt concept, such as No Copy Constructor or Assignment
Operator, with
its very important consequence that you'll use pointers everywhere,
and its rationale
here, or Qt's
"no exceptions" motto, explained
here, from
"historical and practical reasons" to quote the documentation, and if
I'm not mistaken was not supported at all before Qt>=5. When doing
Qt, do full Qt. The hardcore C++, thought available, is buried under the
surface.
You should delete it in act(). Otherwise you may lose trace of it. It is not a good idea to initialize memory and then transfer the pointer to an object (unless of course the situation requires it). My advice is to move the new for A in the GUIObject's constructor. When GUIObject is deleted you can safely eliminate A without running into a double memory free.
Something like this:
class GUIObject {
A* aobj;
public:
GUIObject();
~GUIObject();
};
GUIObject::GUIObject()
{
A* aobj = new B();
}
GUIObject::~GUIObject()
{
delete aobj;
}
I have a setup with a base class that inherits from enable_shared_from_this
class Object : public enable_shared_from_this<Object>
{ ... };
I inherit from enable_shared_from_this because I need to call shared_from_this() every so often. In certain derivations of Object, I need to call shared_from_this() from with in the constructor, which can't be done:
class Thing : public Object
{
public:
Thing() : Object(...)
{ doSomething(shared_from_this()); /* error */ }
};
So a work around is two-phase construction.
class Thing : public Object
{
public:
Thing() : Object(...) { }
void Init() { /* safe to call shared_from_this here */ }
};
A valid way to create a Thing object would be:
shared_ptr<Thing> thing = make_shared<Thing>();
thing->Init();
This is not very nice and error prone but at least it works. However, now there's an issue with further inheritance:
class Bling : public Thing
{
public:
Bling() : Thing(...) { ... }
void Init() { /* safe to call shared_from_this here */ }
};
// How do we create a Bling object?
shared_ptr<Bling> bling = make_shared<Bling>();
static_cast<Thing*>(bling.get())->Init(); // horrible
bling->Init();
// Maybe Bling::Init should look like:
// Bling::Init() { Thing::Init(); /* + other stuff */ }
// then we could do:
shared_ptr<Bling> bling = make_shared<Bling>();
bling->Init(); // etc
Is there a safer or cleaner way to do this? For example, API wise its less error prone to make the constructors for Object, Thing and Bling private and use a static Init() function that creates the shared_ptr:
static shared_ptr<Bling> Bling::Init() {
auto bling = make_shared<Bling>();
Bling::init(bling);
return bling;
}
static void Bling::init(shared_ptr<Bling> bling) {
/* chain parent class init */
Thing::init(bling); // sig: Thing::init(shared_ptr<Thing>);
/* do init stuff */
}
// calls Object(), Thing(), Bling(),
// Object::init(), Thing::init(), Bling::init()
auto bling = Bling::Init();
Basically I'm looking for patterns to implement object creation in a way where I can use a shared_ptr to the object during creation. I need to allow for basic inheritance. I would like suggested methods to consider end-user ease of use and developer maintainability.
You probably should not rely on the fact that the user of an object initially always holds it in a shared pointer. Design the class such that objects are allowed on the stack and heap.
How to solve this depends on what you do with the pointer returned by shared_from_this().
The one thing that comes to my mind is that the object registers itself somewhere - i.e. outside of the object. In my opinion it is better to do that outside of the data classes derived from Object. If you have a registry object of class Registry, turn it into a factory (as suggested by David Schwartz):
class Registry;
class Object
{
protected:
Object() = default;
friend Registry;
public:
// ...
};
class Thing : public Object
{
protected:
Thing() = default;
friend Registry;
public:
// ...
};
class Registry
{
vector<shared_ptr<Object>> store;
public:
shared_ptr<Thing> CreateThing()
{
shared_ptr<Thing> newThing = make_shared<Thing>();
newThing->init(); // If you like.
store.push_back(newThing);
return newThing;
}
shared_ptr<Bling> CreateBling();
// ...
};
No need for enable_shared_from_this at all.
Easier to understand.
Responsibilities clear.
Easily changed such that unregistered Object and Thing objects are allowed. (Scratch the protected constructor and the friend declaration.)
It might already be clear, but just to be sure: I am not in favor of enable_shared_from_this. It makes the assumption, that the object is managed by a shared_ptr at the time shared_from_this() is called. If this is not the case, the "behavior is undefined". If at least it would be an exception or nullptr would be returned...
Such assumptions are ok, when the creation of the initial shared_ptr and the call of shared_from_this() are close to each other in the code (whatever that means). Does anyone have a use case for this? I don`t.
I have a class which carries a couple of dependencies which I'd like to mock using Google Mocks, in order to test the class with Google Test.
Simplified, I have the following1:
template<typename TDep>
class SUT {
private:
TDep dependency;
public:
explicit SUT(const TDep& dep) : dependency(dep) { }
SUT(const SUT& other) : dependency(dep.other) { }
// some methods that use the dependency
}
I also have an interface for the dependency,
class IDependency {
public:
virtual double calculateCoolStuff(double) const = 0;
virtual ~IDependency() { };
}
and a mock object
class MockDependency {
public:
MOCK_CONST_METHOD1(calculateCoolStuff, double(double));
};
However, when I try to compile something like
MockDependency mock;
SUT sut(mock);
I get errors stating error: use of deleted function MockDependency(const MockDependency&), i.e. there is no copy-constructor of the mocked object. I found this discussion on Google Groups which basically ends in making mock objects non-copyable, but allowing the user to add a copy constructor and define copy behavior manually. Very well:
class MockDependency {
public:
MockDependency(const MockDependency& other) { }
MOCK_CONST_METHOD1(calculateCoolStuff, double(double));
};
Now my code compiles, but if I run something like
MockDependency mock;
SUT sut(mock);
EXPECT_CALL(mock, calculateCoolStuff(2.0)).WillRepeatedly(Return(3.0));
sut.doStuff(); // Calls calculateCoolStuff
in a test, I get an error stating that the call was never set up. In other words, the instance mock which I can use to setup expectations, is no longer the same as the instance on SUT used for calculations. This makes testing with GMock and DI difficult, to say the least...
What is the best solution to this?
1) Yes, I'm using poor man's DI. Not the topic of this conversation...
You can use dependency injection with references by ensuring that your class member is a reference:
template<typename TDep>
class SUT {
private:
TDep& dependency; // Reference
// etc.
}
Note that you no longer need a copy constructor on MockDependency. As a rule, you need access to all instances of mock objects being used by your SUT to set up expectations on them.
I've never developed using Test Driven Development, and I've never used Mock Objects for unit testing. I've always unit tested simple objects that don't incorporate other aspects of the application, and then moved on to less simple objects that only reference objects that have already been unit tested. This tends to progress until the final "unit" test is a component test.
What design techniques are used to make the replacing of internal classes with Mock Objects as easy as possible?
For example, in my code, I would include the header file for myDataClass within myWorkerClass. myDataClass is constructed by myWorkerClass, and its lifetime is tied to myWorkerClass. How can you set it up so that it would include a mock myDataClass when the include is hard-wired?
A beginners answer would be:
in tested class don't use the actual
type of mocked one, use its
interface
while testing provide
another realization of mocked object
interface
//Common header
class ObjectInterface {
public:
virtual void doThings()=0;
};
//Release
class RealObject: public ObjectInterface {
public:
virtual void doThings(){
//Complicated work here
}
};
//Testing
class MockedObject: public ObjectInterface {
public:
virtual void doThings(){
//Not so complicated work here
}
};
//Common header
class TestedClass {
public:
void useObject(ObjectInterface & object) {
object->doThings();
}
};
//Unit test
TestedClass toTest;
MockedObject mockedObject;
toTest.useObject(mockedObject);
You could look to adapt your code to follow an (Abstract) Factory Design pattern, whereby a different factory could be used in a unit test environment that would create your mock objects.
One way would be to not hard-wire your classes like that.
Using your example:
myDataClass would be a pure virtual class. This would have at least 2 implementations, the 'real' one and the mock.
Your test code could inject a mock instance by having 2 constructors, one that takes a 'myDataClass' and one that doesn't. See the code below for an example.
class myWorkerClass {
public:
myWorkerClass(myDataClass * dc) : m_dc(dc) {}
myWorkerClass() : m_dc(new MyRealDataClass()) { }
~myWorkerClass { delete m_dc; }
private:
myDataClass *m_dc;
}
Now, you can provide any implementation of the myDataClass to the myWorkerClass you want. If you don't provide an implementation, then your code falls back on the 'real' implementation.
Another technique would be to use the Factory pattern to instantiate your objects. Your test code could set some flag on the factory that creates instances of myDataClass and have it produce a mock object instead of the real one. I prefer the first technique as to me it's a little easier to use (plus I don't have to maintain a factory class for everything I want to test)