I have a class A that instantiates an object of class B in its constructor. I want to test A with a mock object of B.
And no, I can not pass object of B as a parameter. Is there any other way?
I saw an article http://www.ibm.com/developerworks/library/j-mocktest/index.html, with "Mock in the Middle" as the interesting topic, but that is in Java. Is it possible in C++?
class B {...};
class A {
private:
B* b;
public:
A() {
b = new B();
}
~A() {..}
};
EDIT:
In general, the object may be created in some other method, on demand. For example,
class A {
...
int doSomething() {
// Create an object of class B
b = new B();
}
};
You can use factory pattern
given this code
class B {
public:
virtual std::string name() { return "B::name"; }
virtual ~B() {}
};
class A {
private:
std::unique_ptr<B> b;
public:
A() {}
void createB() {
b.reset(new B); // you want to replace `new B` with something else right?
}
void print() {
std::cout << (b ? b->name() : std::string()) << std::endl;
}
~A() {}
};
with factory function
class A {
private:
std::unique_ptr<B> b;
public:
std::function<std::unique_ptr<B>()> b_maker;
A() {
// default maker
b_maker = []{ return std::unique_ptr<B>(new B); };
}
A(std::function<std::unique_ptr<B>()> func) {
b_maker = func;
}
void createB() {
b = b_maker();
}
void print() {
std::cout << (b ? b->name() : std::string()) << std::endl;
}
~A() {}
};
create A with default B is same
A();
and now you can supply mocked B with
A([]{return std::unique_ptr<B>{new MockedB};});
you can also make b_maker
to be a global variable so you don't need to pass it around (but I don't recommended to to it)
you can do it with the complicated way with AbstractBFactory
, BFactory
, MockBFactory
, but it is too much overhead and looks like Java...