I have below piece of code written:
//Source code sample
//Class A is the class under test
class A{
public:
A(){
B *b = new B;
}
void func1()
{
b->func2();
}
};
class B
{
void func2()
{
//here a function from third class is called.
}
};
//Test case
class MockB : public B
{
MOCK_METHOD0(func2(), void());
}
TEST_F(A, TC1_func1)
{
MockB mock;
A *a = new A;
a->func1();
EXPECT_CALL(mock, func2()).Times(1);
}
Here the body of func1 contains just a call to func2. I want to write a test case for func1.
My question is, how can we test whether the func2() is called or not from func1?
Note:
class A creates the instance of class B
I do not want to pass the pointer of class B as an argument to the constructor of class A
I do not want to make any changes to the source code.
Thanks in advance.
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.
class A {
private:
char a;
char sub_f(char *);
public:
A();
char f(char* ) {some actions using sub_f(char*);}
};
class B {
private:
char b;
public:
B();
void execute() { b = f("some text");} //PROBLEM IS HERE
}
Can smb explain me how can I call f(char *) function which is a member of class A, from the void B::execute() ? I can't compile it right now. If I make f(char*) a friend function of the class A, there is another problem appear :
friend f(char*) doesn't know anything about private function sub_f(char*) .
I am a beginner in C++ and will be appreciate for full answers with explanation.
If you have a public member function, like
class A {
public:
char f(char* );// {some actions using sub_f(char*);}
};
you can call it on an instance
A a;
char just_one_char = a.f("Whatever");
The same applies across the board - to call this member function you need an instance.
One approach would be to make your class B have a member variable of type A:
class B {
private:
char b;
a a;
public:
B();
void execute() { b = a.f("some text");} //PROBLEM Solved
};
If f doesn't need any instance data from class A it could be static, or a free function.
Perhaps there isn't a one-to-one relationship between B and A like this.
Perhaps execute could make an A when it needed to:
class B {
private:
char b;
public:
B();
void execute() {
A a;//just needed for this function call, rather than lifetime of B
b = a.f("some text"); //PROBLEM is solved a different way
}
};
Let's consider two classes A and B with the following interface:
class A {
public:
virtual void start() {} //default implementation does nothing
};
class B {
public:
void start() {/*do some stuff*/}
};
and then a third class which inherits from both, A publicly because it implements this "interface", and B privately because that's implementation detail.
However, in this specific implementation, start() only has to contain a call to B::start(). So I thought I could use a shortcut and do the following:
class C: public A, private B {
public:
using B::start;
};
and be done with it, but apparently it doesn't work. So I get using private base function doesn't work in order to override virtuals. From that, two questions:
Is there any way to make this work as I supposed it may have worked?
Why would the compiler accept this code as valid? As I see it there are now two start() functions with the exact same signature in C and yet the compiler seems fine with it and only calls A::start().
EDIT: A few precisions:
The goal is to manipulate C objects through A pointers.
I'm currently using a simple function that just calls B::start(), I was specifically wondering if a using declaration could indeed "override" a virtual, and if not, how this was allowed to have both functions coexist.
I might have omitted a few things like virtual inheritance for simplicity.
Is there any way to make this work as I supposed it may have worked?
You should override the member function and explicitly call B::start():
class C: public A, private B {
public:
void start() override { B::start(); }
};
Why would the compiler accept this code as valid? As I see it there
are now two start() functions with the exact same signature in C and
yet the compiler seems fine with it and only calls A::start().
You are right, there are two member functions accessible in C (A::start() and B::start()). And in class C, without overriding start() or making the start() of any of the base classes visible by doing a using ...::start(), you will have ambiguity error when trying to call the member function using unqalified namelookup from an object of C.
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
};
int main(){
A* a = new C();
a->start(); //Ok, calls A::start()
C* c = new C();
c->start(); //Error, ambiguous
}
To fix that, you will have to use the qualified name such as:
C* c = new C();
c->A::start(); //Ok, calls A::start()
Now, doing a using B::start() in class C simply declares the start() to refer to B::start() whenever such name is used from an object of C
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
using B::start();
};
int main(){
A* a = new C();
a->start(); //Ok, calls A::start()
C* c = new C();
c->start(); //Ok, calls B::start()
}
using B::start makes the function void B::start() visible in C, it does not override it. To call make all the above unqualified member function call, to call B::start(), you should override the member function in C, and make it call B::start()
class A {
public:
virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
void start() override { B::start(); }
};
int main(){
A* a = new C();
a->start(); //Ok, calls C::start() which in turn calls B::start()
// ^^^^^^^^^^^^^^^^ - by virtual dispatch
C* c = new C();
c->start(); //Ok, calls C::start() which in turn calls B::start()
}
Say I have a class:
class Foo{
public:
Foo(){
}
//Is it possible to create a function like this:
virtual Foo* createOb(){
//Should create a new Foo,Bar or Fiz, depending on the actual object type.
}
}
class Bar: public Foo{
public:
Bar(){
}
}
class Fiz: public Foo{
public:
Fiz(){
}
}
Is it possible to have a method createOb() in the base class, so when createOb() is called on an instance of one of the derived classes, that an instance of the derived class is created ?
Yes, it can be done, using CRTP.
Bu first, returning a raw pointer obtained from new is very dangerous. In c++ raw pointers should be used only when they do not have ownership of the pointed object. So I took the liberty to use unique_ptr:
struct Base {
virtual auto create_obj() -> std::unique_ptr<Base>
{
return std::unique_ptr<Base>{};
}
};
// abstract works too:
struct Base {
virtual auto create_obj() -> std::unique_ptr<Base> = 0;
};
template <class Derived>
struct Base_crtp : Base {
auto create_obj() -> std::unique_ptr<Base> override /* final */
{
return std::unique_ptr<Base>{new Derived{}};
}
};
struct D1 : Base_crtp<D1>
{
};
struct D2 : Base_crtp<D2>
{
};
And then:
auto b1 = std::unique_ptr<Base>{new D1{}};
auto b2 = std::unique_ptr<Base>{new D2{}};
auto new_d1 = b1->create_obj();
auto new_d2 = b2->create_obj();
Definitely YES!!!
When a method is declared virtual in base class, and called through the derived class object, then the derived class function gets called (Read vprt, vtable concept in c++).
#include <iostream>
using namespace std;
class A{
public:
virtual A* getobj(){
return new A();
}
};
class B: public A{
public:
B(){cout<<"B constructor"<<endl;}
virtual A* getobj(){
return new B();
}
};
int main()
{
A *a = new B();
A *second = a->getobj();
return 0;
}
In the above code, we are calling the getobj() function using class B's object.
Here the constructor of class B is called twice.
first, for new B() in main
secondly for getobj function call which again creates object of B
This is not an optimal solution, but it works.
In your .h
class Foo{
public:
Foo();
virtual Foo* createOb();
};
class Bar: public Foo{
public:
Bar();
};
class Fiz: public Foo{
public:
Fiz();
};
In your .cpp
#include "Header.h"
Foo::Foo() {}
Foo* Foo::createOb(){
if (dynamic_cast<Bar*>(this)) {
return new Bar();
}
else if (dynamic_cast<Foo*>(this)) {
return new Foo();
}
return nullptr;
}
Bar::Bar() {}
Fiz::Fiz() {}
As already suggested please consider a pure virtual method
No, this is not possible with "pure" inheritance. The classes must override createOb() member function in order to support cloning.
You can see why this is not possible by considering separate compilation of classes. An implementation of one-fits-all createOb() member function must be completed in isolation from Bar and Fiz, making it impossible for the base to know the type of its subclasses.
An implementation with a pure virtual function in the base is very common, though.
Another approach is to use Curiously Recurring Template Pattern (CRTP) to implement cloning. This article explains how it can be done.
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.