my code is structured like this
class B
{
virtual void bar() { //something};
}
class A {
void foo(B& b) { b.bar();}
}
I wanted to create a gtest mock for this but I'm running into an issue...
class Btest : public B
{
public:
MOCK_METHOD(void, bar, (), (override));
};
TEST()
{
A a;
Btest b;
a.foo(b); <--- no instance matches argument list
}
How do I implement a mock like this? If I upcast wouldn't it just call the non mocked version of that method?
There are several issues with your code. One way to fix it is to make the bar and foo methods public:
class B {
public:
virtual void bar() {
// something
}
};
class A {
public:
void foo(B& b) { b.bar(); }
};
class Btest : public B {
public:
MOCK_METHOD(void, bar, (), (override));
};
TEST(a, b) {
A a;
Btest b;
a.foo(b);
}
Related
I have a class C that inherits both from Ai and B. A and B are unrelated. This is all best explained with the code below. In main(), I have a variable a defined as std::unique_ptr<A>, but initialized with C. I cannot change this definition.
My question is, given a defined like this, how can I call functions defined in B or C or Ai correctly?
#include <memory>
class A
{
public:
void fun_a() {}
};
class B
{
public:
void fun_b() {}
};
class Ai : public A
{
public:
void fun_ai() {}
};
class C: public Ai, public B
{
public:
void fun_c() {}
};
int main()
{
// I cannot change the following definition:
std::unique_ptr<A> a = std::make_unique<C>();
a->fun_a();
//a->fun_b(); // How ?
//a->fun_c(); // How ?
//a->fun_ai(); // How ?
return 0;
}
You can static_cast to C*:
static_cast<C*>(a.get())->fun_b();
static_cast<C*>(a.get())->fun_c();
static_cast<C*>(a.get())->fun_ai();
or you could make it polymorphic:
class A {
public:
virtual ~A() = default;
void fun_a() { std::cout << "fun_a\n"; }
};
and then dynamic_cast:
dynamic_cast<B*>(a.get())->fun_b();
dynamic_cast<C*>(a.get())->fun_c();
dynamic_cast<Ai*>(a.get())->fun_ai();
Note: dynamic_casts to pointer types may fail and return nullptr so, if there's any doubt, check the return value.
Demo
Consider this trivial C++11 inheritance example:
class A
{
public:
virtual void func() = 0;
};
class B : public A
{
public:
void func() { func1(); /* Wish this could be func1() or func2()! */ };
void func1() { /* Does one thing */ };
void func2() { /* Does another thing */ };
};
void doSomeStuff(A &a)
{
a.func();
}
int main()
{
B b;
doSomeStuff(b);
return 0;
}
I'm trying to make it so that I don't have to modify (or duplicate) class A's definition or the function doSomeStuff, but I want the invocation of a.func() to call either func1() or func2() of B. Ideally I'd change the line doSomeStuff(b) to something like doSomeStuff(b.butWithFunc1) but I'd also be OK with some way to modify B's version of func() so that it can make the decision internally to call func1 or func2 based on some parameter.
The same object of type B may have to sometimes call func1 or func2 during an invocation of func, so I can't use a persistent member of class B to decide. Adding a parameter to func() would make this trivial as well, but that's not something I can do either.
I'm kind of wondering if there's some way to add to class B a function that returns a mutated version of class B which calls func2() from func(), or if I can play some tricks with function pointers or something. However, something tells me I'm Doing It Wrong and the obvious solution is staring me in the face.
If it helps for context, class A is similar to a std::lock_guard, and it works fine for things like semaphores and mutexes (for which there is only one definition of lock and unlock), but class B in this example is a R/W lock - so there's a "readLock" and "writeLock", and I'd like to be able to say something like "auto lock this RW lock as a read lock" without having to duplicate/break the auto lock code.
For instance:
{
A_AutoSem(myMutex); // calls lock() on myMutex
//... do some stuff
// end of the block, ~A_AutoSem calls unlock on myMutex
}
{
A_AutoSem(B_RWLock); // how do I say here "call readLock"?
// ... do some stuff
// end of the block ~A_AutoSem should call "readUnlock" on B_RWLock
}
Simply define some additional classes to call func1() and func2(), and then pass those classes to doSomeStuff() instead of passing B directly.
Try something like this:
class A
{
public:
virtual void func() = 0;
};
class B
{
public:
void func1() { /* Does one thing */ };
void func2() { /* Does another thing */ };
};
class C1 : public A
{
private:
B &m_b;
public:
C1(B &b) : m_b(b) {}
void func() override { m_b.func1(); }
};
class C2 : public A
{
private:
B &m_b;
public:
C2(B &b) : m_b(b) {}
void func() override { m_b.func2(); }
};
void doSomeStuff(A &a)
{
a.func();
}
int main()
{
B b;
{
C1 c(b);
doSomeStuff(c);
}
{
C2 c(b);
doSomeStuff(c);
}
return 0;
}
Live Demo
Alternatively:
class A
{
public:
virtual void func() = 0;
};
class B
{
private:
void func1() { /* Does one thing */ };
void func2() { /* Does another thing */ };
public:
class C1 : public A
{
private:
B &m_b;
public:
C1(B &b) : m_b(b) {}
void func() override { m_b.func1(); }
};
class C2 : public A
{
private:
B &m_b;
public:
C2(B &b) : m_b(b) {}
void func() override { m_b.func2(); }
};
};
void doSomeStuff(A &a)
{
a.func();
}
int main()
{
B b;
{
B::C1 c(b);
doSomeStuff(c);
}
{
B::C2 c(b);
doSomeStuff(c);
}
return 0;
}
Live Demo
class A
{
public:
void doFirstJob()
{
// Do first Job.
}
}
class B : public A
{
public:
virtual void doSecondJob()
{
// Do Second Job.
}
}
class C
{
public:
void doSomething() {
b->doFirstJob();
b->doSecondJob();
}
private:
B* b;
}
Now I should write unit test code for class C, then I'll write a mock for class B, but the problem is how to mock the method doFirstJob().
Bluntly, I want know how to mock the non-virtual method of the parent class???
Can any one help me ??
Typemock Isolator++ supports mocking non virtual methods of a parent class (same as faking a method of the class under test).
See following example:
class A
{
public:
int doFirstJob()
{
return 0;
}
};
class B : public A
{
};
class C
{
public:
int doSomething()
{
return b->doFirstJob();
}
void setB(B* to)
{
b = to;
}
private:
B* b;
};
In the test You create a fake of B -> change the behavior of doFirstJob to return 3 -> continue with your test as you would normally write it.
TEST_CLASS(NonVirtualMethod)
{
public:
TEST_METHOD(NonVirtualMethodTestOfBaseClass)
{
B* fakeB = FAKE<B>();
WHEN_CALLED(fakeB->doFirstJob()).Return(3);
C c;
c.setB(fakeB);
int first = c.doSomething();
Assert::AreEqual(3,first);
}
}
You can find more examples here.
I want to call a method from A class in constructor of other class
I googled, but did not find any answer
For example, I have :
class A{
void doWork();
}
class B{
B(){
//here i want to have doWork method
}
}
You told us not enough to choose proper solution. Everything depends on what you are trying to achieve. A few solutions:
a) Mark A method as static.
class A
{
public:
static void DoSth()
{
// Cannot access non-static A members here!
}
};
class B
{
public:
B()
{
A::DoSth();
}
};
b) You can instantiate A in place
class A
{
public:
void DoSth()
{
// Do something
}
};
class B
{
public:
B()
{
A a;
a.DoSth();
}
};
c) You can put A's instance into B:
// A remains as in b)
class B
{
private:
A a;
// or: A * a;
public:
B()
{
a.DoSth();
// or: a = new A; a->DoSth();
// Remember to free a somewhere
// (probably in destructor)
}
}
d) You may derive B from A:
class A
{
protected:
void DoSth()
{
}
};
class B : public A
{
public:
B()
{
DoSth();
}
};
e) You can forget about A class and make DoSth a function:
void DoSth()
{
// ...
}
class B
{
public:
B()
{
DoSth();
}
}
Since you provided not enough data, you have to choose solution on your own.
In order for that to work you'd need to subclass it.
So it'd be like this:
class A {
doWork();
}
class B : A {
B(){
doWork();
}
}
You could also do it like so going for a HAS-A rather than IS-A relationship:
class A {
doWork();
}
class B {
A myA;
B(){
myA.doWork();
}
}
Without knowing more of what you are doing I'd go with the top (IS-A) solution which is what I think you are trying to do.
Or
class A
{
public:
static void doWork();
};
class B
{
B(void)
{
A::doWork();
}
};
?
PS: Here B::B() will be private
Is there a nice way to call A::foo() from B::bar() in the following sample?
class A {
protected:
void foo() {}
};
class B : public A {
public:
void bar(A& a) { // edit: called with &a != this
a.foo(); // does not work
}
};
I can't think of anything other than declaring B to be a friend of A, but that could get pretty ugly with some more classes.
Any ideas?
Yes, you can use a base-class function.
class A {
protected:
void foo() {}
void do_other_foo(A& ref) {
ref.foo();
}
};
class B : public A {
public:
void bar(A& a) { // edit: called with &a != this
this->do_other_foo(a);
}
};
Why are you passing object of type A? You could do like this :
class B : public A {
public:
void bar() {
foo();
}
};
or, like this
class B : public A {
public:
void bar() {
A::foo();
}
};
Here's an approach to giving "protected" like access, allowing calls by any derived classes or object.
It uses a protected token type, required to un-lock privileged methods:
struct A
{
protected:
//Zero sized struct which allows only derived classes to call privileged methods
struct DerivedOnlyAccessToken{};
public: //public in the normal sense :
void foo() {}
public: //For derived types only :
void privilegedStuff( DerivedOnlyAccessToken aKey );
};
struct B: A
{
void doPrivelegedStuff( A& a )
{
//Can create a token here
a.privilegedStuff( DerivedOnlyAccessToken() );
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.foo();
a.privilegedStuff( A::DerivedOnlyAccessToken() ); // compile error.
B b;
b.doPrivelegedStuff( a );
return 0;
}
This is not my idea. I read it some place. Sorry I dont recall who's cunning idea it was.
I expect the compiler can elide the aKey parameter.