How to simulate an EXPECT_CALL with gtest - c++

In the code below I tried to explain my problem on a basic model.
class A
{
public:
A() {}
virtual void foo() {}
virtual ~A(){}
//...
};
class B : public A{
public:
B(){}
//...
//does not contain the override function foo()
};
class MustBeTested{
public:
MustBeTested(){
//...
}
void function()
{
m_elem->foo();
//...
}
private:
B* m_elem;
};
class Mock : public B {
public:
Mock() {}
MOCK0(foo, void());
};
//test function from above class
void TestFunction
{
Mock* dummy = new Mock;
EXPECT_CALL(*dummy, foo()).Times(1);
//i know it is wrong becase the called method is A::foo();
}
I have a basic class A that contains a virtual method.
Derivative class B no longer contains the overwritten method foo ().
The MustBeTested class contains the function to be tested, the class member is type B *.
Initially without looking I started to make a Mock class derived from B to simulate EXPECT_CALL ().
I realized that it is not possible because the method in A :: foo () will always be called.
My question is, if there is a workaround without making changes to the class A or B code?

foo in B is not overriden, but it is there - with the default implementation from A. foo is virtual and can be overriden in classes that derive from B, like your Mock (that wouldn't be possible if foo was marked final in B). Your code will work if you will use dependency injection in MustBeTested, see Dependency injection with unique_ptr to mock.

Related

google mock - how to mock object owned by class under test

In this example
class A
{
public:
A();
~A();
virtual void func1();
virtual void func2();
protected:
virtual void func3();
private:
// How do I mock this
NetworkClass b;
}
How do I mock NetworkClass b object?
I don't think it's possible to do this solely using google-mock macros.
You'd have to redefine the identifier NetworkClass to actually mean NetworkClassMock and then (for purpose of the test) rename the original NetworkClass to something else like NetworkClass_Orig.
But that still doesn't help you access the private member NetworkClass b for the purpose of the test.
You cannot mock b as it is. You will need to use Dependency Injection.
First you will need to specify a Base Class (or interface) and derive your NetworkClass and NetworkClassMock from INetworkClass. Then you can pass aa raw pointer (better a smart pointer like std::unique_ptr) or a reference to class A. This input can be either your real implementation NetworkClass or your mock NetworkClassMock.
See this example:
#include <iostream>
class INetworkClass
{
public:
virtual void doSomething() = 0;
};
class NetworkClass : public INetworkClass
{
public:
void doSomething() override {std::cout << "Real class" << std::endl;} ;
};
class NetworkClassMock : public INetworkClass
{
public:
void doSomething() override {std::cout << "Mock class" << std::endl;};
};
class A
{
public:
A(INetworkClass& b) : b(b) {};
~A() {};
void func1() {b.doSomething();};
private:
// How do I mock this
INetworkClass& b;
};
int main(){
NetworkClass real_class;
NetworkClassMock mock_class;
A a1(real_class);
A a2(mock_class);
a1.func1();
a2.func1();
return 0;
}
If you just want to access your private member, e.g. to read it's value after doing some tests you should redesign your code. Accessing private members from outside your class is not a good design. If you still want to do this you could check this answer (written for C# instead of C++ but still usable).
P.S. To use the override keyword you will need to compile with C++11 support.

GMOCK base class methods in derived class

I have a class that is inherited from another class as mentioned below:
class A
{
public:
virtual void Show(){}
};
class B : public A
public:
void BMethod1(){Show()}
};
Now I am writing test cases for class B - so I have mocked class A :
class MockA : public A
{
MOCK_METHOD0(Show, void());
};
Below is my Google Test framework test case:
TEST(BTEST , ShowMethod)
{
B bobj;
MockA aobj;
EXPECT_CALL(aobj , Show());
bobj.BMethod1(); // updated as from bobj.METHOD0()
}
But the test cases is calling the actual A::Show() implementation - how can call the Mocked version of MockA::Show() in such a case?
====================UPDATE=================================
Well the below implementation did the trick for me:
class A
{
public:
virtual void Show(){}
};
class B : public A
public:
void BMethod1(){Show()}
};
class BMock : public B
{
public:
MOCK_METHOD0(Show, void());
};
Now use BMock object to test you class B required methods
You have to make Show() virtual to get MockA::Show() instead of A::Show().
First off:
bobj.METHOD0();
is totally wrong. METHOD0 is no valid symbol to access a mocked function.
What you want to test is that B::BMethod1() calls A::Show(), right?
So change that line to
bobj.BMethod1();
You can change class B to take it's base class implementation as a template parameter:
class A
{
public:
virtual void Show(){}
// ^^^^^^^ See note 1
};
template<class Base>
class B : public Base
public:
void BMethod1(){Show()}
};
Then you use
B<A> bobj;
bobj.BMethod1();
in your production code, and
B<MockA> bobj;
EXPECT_CALL(bobj , Show());
bobj.BMethod1(); // <<< trigger the expectation
in your unit test code.
As a side node:
It's a well known pattern to inject base classes through template type parameters called Mixin.
Though Mixins are mainly meant to provide piecewise implementations of interfaces, which are mainly meant to compose public interface implementations.
However, hitting such case when trying to unit test a class regarding those manners, would automatically lead me to the question, if I have a design flaw there:
Is B really an A, or is it rather meant to use an instance of A as an owned or referenced member variable?
If I'm coming up with the need to test such in a unit test, I'd consider refactoring class B to something like
class B {
A& a_;
public:
B(A& a) a_(a) {}
void BMethod1() { a_.Show(); }
};
And adapt the test scenarios accordingly:
TEST(BTEST , ShowMethod)
{
MockA aobj;
B bobj(aobj);
EXPECT_CALL(aobj , Show());
bobj.BMethod1();
}
As for your comment
The intention is that the test case can return mocked values - EXPECT_CALL(mMockA, show()) .WillOnce(Return(false));
This should work with the example above:
EXPECT_CALL(bobj, Show()) .WillOnce(Return(false));
But requires that Show() is declared like
virtual bool Show();
in class A and like
MOCK_METHOD0(Show, bool());
in the MockA class.
1)The virtual declaration is necessary in order to allow MockA to override the original implementation.
Well the below implementation did the trick for me:
class A
{
public:
virtual void Show(){}
};
class B : public A
public:
void BMethod1(){Show()}
};
class BMock : public B
{
public:
MOCK_METHOD0(Show, void());
};
Now use BMock object for your test cases
You can use Isolator++ to create the test without the setup:
class A
{
public:
void Show() {}
};
class B : public A
{
public:
void BMethod1() { Show(); }
};
TEST(BTEST, ShowMethod)
{
B bobj;
auto aobj = FAKE<A>();
bobj.BMethod1();
ASSERT_WAS_CALLED(aobj->Show());
}

How do I use composition and inheritance together?

I've a case where an object and a collection of objects behave similarly. So to represent the object I've a class:
class A {
public:
virtual void foo();
protected:
int x;
};
And to represent the collection of objects, I've another class:
class Collection: public A {
void foo(); //override base class function
private:
vector<A*> aList;
}
This is fine, but the issue is that Collection class will have a copy of A::x which I don't need. I don't want class Collection to inherit the data members. How do I achieve this?
Note: I can't edit "class A" because it is from a library.
Correction: I can't change the interface of A. A is being used in rest of the code. I can modify the implementation. I can change A::anyFunction() to virtual if it is already not virtual. I can change a private member to protected.
You can use an interface:
class AInterface {
public:
virtual void foo() = 0;
};
and then
class A : public AInterface {
/*...*/
};
class Collection : public AInterface {
/*...*/
};
If you cant edit A you could still use the interface, by writing a wrapper:
class AWrapper : public AInterface {
void foo() { a.foo(); }
private:
A a;
};

How to mock a member variable of dependency?

I've got a class and member:
class A
{
B obj;
public:
int f(int i){return obj.g(i);}
}
Here B obj is a dependency that requires run-time creation from a file. In my unit test for class A, I wish to mock B obj, with a function g typed int(int).
How can I write my test code, to mock B obj, and then test A::f.
Thanks a lot.
You need to use dependency injection to achieve this. To this end, have class B inherit from an interface, and have class A hold a pointer to that interface:
class IB
{
public:
virtual void g(int i) = 0;
};
class B : public IB
{
public:
void g(int i) {
// this is your real implementation
}
};
Also, to enable dependency injection in class A, add appropriate constructor or setter method:
class A
{
private:
IB *obj;
public:
A() : obj(nullptr) {}
// You don't need both the constructor and setter, one is enough
A(IB *pB) : obj(pB) {}
// void setB(IB *pB) { obj = pB; }
int f(int i) { return obj->g(i); }
};
Now, in your production code you create an object of class B and pass it to class A object (assuming that we are using the constructor for injection):
B b;
A a(&b);
During testing phase, you create a mock class BMock and pass an object of that class to class A object:
class BMock : public IB
{
public:
MOCK_METHOD1(g, int(int));
};
TEST(ATests, TestCase1)
{
BMock bmock;
A a(&bmock);
// Now you can set expectations on mock object, for example that g will
// return 100 when it receives 50 as argument
EXPECT_CALL(bmock, g(50)).WillOnce(Return(100));
// Now act by calling A::f, which will in turn call g from mock object,
// and assert on function return value
ASSERT_EQ(a.f(50), 100);
}
To do this, take a pointer of B instead of object in class A and make your unit Test class (FixtureA ) as friend class in A.
class A
{
B *obj;
public:
int f(int i){return obj.g(i);}
friend class FixtureA;
};
In FixtureA.h you can have following code
class FixtureA
{
public:
void Testf();
}
In FixtureA.cpp
TEST_F(FixtureA , Testf)
{
Testf();
}
void FixtureA::Testf()
{
A objA;
objA.obj = new BMock();
objA.f(2);
}
In BMock class , you can mock the g() function.
You can't do it with the code you have. You have hardcoded your dependency inside the A class. To make mocking possible you have to use some of the dependency injection patterns. One of the possible ways is to have a pointer(better smart) to your B class and in the A constructor you will get a pointer to B with which you will initialize your inner B*. That way you will be able to put a mocked object in your tests.

Figuring out the class of an inheriting object

I have a linked list of Foo objects. Foo is a base class, which has several classes inherit from it. Say, classes A, B, and C.
I am cycling through this linked list and calling a method some_method, which has 3 definitions; one for each child class:
some_method(A a);
some_method(B b);
some_method(C c);
The linked list is generic, so it is of type Foo, as it has an assortment of A, B and C objects.
When I'm cycling through the linked list at current_element, calling some_method(current_element);, how can I make it call the right method? The compiler complained until I wrote a some_method that took the generic Foo, and it only calls into that method.
Depending on your requirements, you may want to consider using polymorphism. To do this, add a pure virtual method to your base node class, and move the corresponding methods to the derived classes.
class Foo
{
public:
virtual void some_method() = 0;
};
class A : Foo
{
public
virtual void some_method()
{
// move the body of some_method(A a) here
}
};
For this to work, your linked list will need Foo*, instead of Foo.
class Node
{
public:
Foo* foo;
Node* next;
};
// ...
Node* someNode = GetNode();
// Calls correct method - A::some_method, B::some_method, or C::some_method
someNode->foo->some_method();
If you can't put some_method in Foo/A/B/C, then you might want to look into the Visitor design pattern:
http://en.wikipedia.org/wiki/Visitor_pattern
This is the "double dispatch" problem. You can use the visitor pattern. Usually the Visitor is a base class so you can re-use this design for multiple problems.
#include <iostream>
class FooVisitor;
class Foo
{
public:
virtual void some_method() = 0;
virtual void visit(FooVisitor* v) = 0;
};
class A;
class B;
class FooVisitor
{
public:
virtual void visit(A* a){ std::cout << "A" << std::endl;}
virtual void visit(B* b){std::cout << "B" << std::endl;}
};
class A : public Foo
{
public:
virtual void some_method()
{
// move the body of some_method(A a) here
}
virtual void visit(FooVisitor* v) { v->visit(this);}
};
class B : public Foo
{
public:
virtual void some_method()
{
// move the body of some_method(A a) here
}
virtual void visit(FooVisitor* v) { v->visit(this);}
};
int main()
{
FooVisitor fv;
Foo* f1 = new A;
f1->visit(&fv);
Foo* f2 = new B;
f2->visit(&fv);
getchar();
}
Two ways:
1) the better way:
Reverse your design such that someMethod is a virtual method of the base class Foo and redefine it in the derived classes. As:
class Foo {
public:
virtual void someMethod() = 0;
};
class A {
public:
void someMethod() { /* implementation specific to A here */ };
};
class B {
public:
void someMethod() { /* implementation specific to B here */ };
};
class C {
public:
void someMethod() { /* implementation specific to C here */ };
};
Then calling the someMethod on a pointer to Foo will automatically call the method from the appropriate class. If that cannot be done because someMethod cannot be implemented as part of Foo or its derivatives (e.g. it needs access to private members of the class it is currently in in your design), then you might try to split this functionality apart into subproblems that can be put into virtual methods of these classes A B C.
2) the "I don't have a choice" way:
Use RTTI (Run-Time Type Identification), it is included in C++. It requires that your base class Foo has at least one virtual method. You need to #include <typeinfo>, then use typeid() on the pointer, it will return a type_info object, and you can compare its name() result with the class names A B and C. This isn't a very nice approach because it has more overhead and it breaks OOP design principles. But if that's the only option, it's fine.
RTTI is your friend here. The example given in the link will guide you further
You can call the method for the child class as a member method. For exampleA a = new A(); a.some_method() should call the correct the method. Within some_method() you can reference to object using keyword this.