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());
}
Related
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.
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;
};
Here's what I mean. I have a class hierarchy:
class A {
virtual int f() = 0;
};
class B : public A {
int f() override {return 5;}
void doSpecificStuff() {}
}
B is a self-sufficient class that can be used on its own. But it also has many descendants:
class C : public B {
int f() override {return 171;}
}
Is there any way to make sure that I won't forget to re-implement f when subclassing B?
This solution is inspired by #dyp's comment:
You could split the two responsibilities of B, namely "provides B-style implementation" and "can be instantiated."
class B_for_implementation : public A
{
void doSpecificStuff();
};
class B_for_objects final : public B_for_implementation
{
int f() override {return 5;}
};
class C final : public B_for_implementation
{
int f() override {return 171;}
};
Self-contained objects would be created from B_for_objects, while other classes would derive from B_for_implementation.
Consider the following example:
class A{
public: virtual void hello() = 0;
};
class B: public A{};
class C {
public: void hello(){
cout<<"Hi";
}
};
class D: public B, public C{};
The idea is that I would like to inject the implementation of hello into D through C. This doesn't seem to work unless I make C inherit from A too. Since that leads to diamond inheritance, I end up using virtual inheritance.
Is there any alternative to forcing an implementation into a derived class, without disturbing the abstract classes A and B here?
EDIT: I want a solution where I don't need to explicitly write code within D. This is because, I have many classes like D having the same implementation, which is exactly why I would like to push that implementation up to some class from which all of them inherit.
You can rewrite C as a template class that inherits from it's template argument and then derive D from C.
template <class Base>
class C : public Base {
public: void hello(){
cout<<"Hi";
}
};
class D: public C<B> {};
You can consider static inheritance/ policy classes when you need to inject an outside method into a class hierarchy. Note that injecting the method usually means that the method does not have the same name as an existing virtual in the class hierarchy (if it does, you are forced to use virtual inheritance or explicitly call with the scope :: or insert it in the class hierarchy). I called the method externalHello here.
The other options work fine as well but they conceptually point more to the fact that the injected method is not really an abstract method that could be used outside of this class hierarchy but should have been part of it in the first place.
class A
{
public:
virtual void hello() = 0;
};
class B: public A
{
public:
void hello()
{
cout<<"Hi from B" << endl;
};
};
template<typename T> class C1
{
public:
void injectedMethodUnrelatedToClassHierarchy()
{
cout<<"Hi from C1 with unrelated method" << endl;
};
void externalHello()
{
static_cast<T*>(this)->hello(); // will still call hello in B
injectedMethodUnrelatedToClassHierarchy(); // this will call hello here
};
};
class D: public B, public C1<D>{};
With client code:
D dx;
dx.hello();
dx.externalHello();
dx.injectedMethodUnrelatedToClassHierarchy();
It may work
#include<iostream>
using namespace std;
class A
{
public:
virtual void hello() = 0;
};
class C {
public: void hello(){
cout<<"Hi\n";
}
};
template<typename T>
class B: public A, public T
{
public:
void hello() override{ //override A::hello()
//do other staff
T::hello(); // call C::hello()
}
};
class D: public B<C>{
};
int main()
{
D d;
d.hello();
return 0;
}
considering following code:
#include <stdio.h>
struct ITimer {
virtual void createTimer() = 0;
};
class A : public ITimer
{
public:
void showA() {
printf("showA\n");
createTimer();
}
};
class B : public ITimer
{
public:
void showB() {
printf("showB\n");
}
void createTimer() {
printf("createTimer");
}
};
class C: public A, public B
{
public:
void test() {
showA();
showB();
}
};
int main()
{
C c;
c.test();
return 0;
}
I need to use interface ITimer in class A, but the method is implemented in class B. So I inherited the interface in A, but the compiler is not happy with it:
test.cc
test.cc(38) : error C2259: 'C' : cannot instantiate abstract class
due to following members:
'void ITimer::createTimer(void)' : is abstract
test.cc(5) : see declaration of 'ITimer::createTimer'
How could I use the interface in baseclass A while its method is implemented in class B.
Thanks.
Inheritance is the base-class of all evil.
A nor B are ITimers
A doesn't even implement the pure virtual, so it cannot be instantiated. Therefore, inheriting from A makes C abstract too (cannot be instantiated).
You don't want to use inheritance here. See
Liskov Substitution Principle ("is-a" rule)
In this case, the dreaded diamond-of-death hierarchy could be fixed by adding virtual:
class A : public virtual ITimer
//...
class B : public virtual ITimer
See it Live on IdeOne. I don't recommend this, though. Consider fixing the design.
See also Diamond inheritance (C++)