I'm a beginner with google mock and I'm not sure how to use it and the concept.
If I'm trying to Test a method from a class that is calling some other methods from different classes.
Do I need to mock all these methods from this different classes that my Test method is calling.
Here is a example:
class A {
public:
A () {}
int setnum(int num) {//do some stuff return 1 or 0//
}
private:
int _num;
};
class B {
public:
B (){}
int init(A *a, int number){
if(a->setnum(number))
return 1;
return 0;
}
void setNum(int num){_num=num;}
private:
A *_a;
int _num;
};
class C {
public:
int doSoemthing(A *a, int number){
if (domore(a,number))
return 1;
return 0;
}
int domore(A *a, int number){
if(_b.init(a,number))
return 1;
return 0;
;}
private:
B _b;
};
Do I need to mock all the methods from class A and B that I need to Test my Test method?
Or can I just mock one Class , and test if this class is working.
In order to test C class with mocks, you need to introduce an interface for the dependency than is to be used in C class (here, added BIface). Then you need to use dependency injection of BIface to C class (via added ctor). Having that you will be able to test interactions of B and C classes. IMO A class doesn't need to be mocked in CTest (but most probably need to be tested in BTest)
class A {
public:
A() {} // not needed
int setnum(int num) { // do some stuff return 1 or 0//
}
private:
int _num;
};
class BIface {
public:
virtual ~BIface() = default;
virtual int init(A *a, int number) = 0;
virtual void setNum(int num) = 0;
};
class B : public BIface {
public:
B() {} // not needed
int init(A *a, int number) override {
if (a->setnum(number))
return 1;
return 0;
}
void setNum(int num) override {
_num = num;
}
private:
A *_a;
int _num;
};
class C {
public:
C(BIface &b) : _b{b} {}
int doSoemthing(A *a, int number) {
if (domore(a, number))
return 1;
return 0;
}
int domore(A *a, int number) {
if (_b.init(a, number))
return 1;
return 0;
;
}
private:
BIface &_b;
};
class BIfaceMock : public BIface {
public:
MOCK_METHOD2(init, int(A *, int));
MOCK_METHOD1(setNum, void(int));
};
TEST(CTest, givenDoingMoreWhenInitOfBReturnOneThenReturnOne) {
// can be done in CTest ctor if more tests are needed to avoid code duplciation
BIfaceMock bMock{};
A a{}; // `a` doesn't need to be mocked in CTest. It shall be mocked in BTest as it is dependency of B class, not C class
C testedObject{bMock}; // dependency injection of BFace to C
const auto SOME_INT_PARAM = 42;
// Eq mather is used to match both &a and SOME_INT_PARAM. This confirms proper parameters were passed to init
EXPECT_CALL(bMock, init(&a, SOME_INT_PARAM)).WillOnce(Return(1));
ASSERT_EQ(1, testedObject.domore(&a, SOME_INT_PARAM));
}
I'm not 100% sure but in your example you don't have to use mocks at all. You can create your objects really easy here.
I would use mocks when I would expect that some method will be called and should return specific value - I'm not testing this method but for example if-statment:
A a;
if(a.method())
{
// some logic
}
To manipulate what if will get I would use mocks like this: EXPECT_CALL(aMock.method()).WillOnce(Return(true));
But you can use it in many more situations (e.g: you can avoid creating really big class and replace it with mock object).
Related
class Builder
{
public:
virtual void Build(int a) = 0;
};
class ConcreteBuilder1 : public Builder
{
public:
void Build(int a);
};
class ConcreteBuilder2 : public Builder
{
public:
void Build(int a. struct A* a);
};
So My question is how to design Build() method to take both parameters(int, struct* A). But with same builder interface ?
So that,
int x;
struct A* y;
Builder concrteBuilder1 = new ConcreteBuilder1();
concrteBuilder1 ->Build() // // Here I am forced to pass struct A* a eventhough not needed for concerte builder1 . And I am also forced to forced to change Builder interface too.
My apologies if I did not convey the question clearly.
Builder usually builds an object of another class. You may try something similar to this:
class ToBuild
{
//some code here
};
class Builder
{
public:
virtual ToBuild * build() = 0;
};
class ConcreteBuilder : public Builder
{
int _valA;
int _valB;
public:
ToBuild * build() override
{
ToBuild * obj = new ToBuild();
//initalize obj using _valA and _valB variables;
return obj;
}
ConcreteBuilder& valA(const int val)
{
_valA = val;
return *this;
}
ConcreteBuilder& valB(const int val)
{
_valB = val;
return *this;
}
};
int main()
{
ConcreteBuilder b;
ToBuild * obj = b.valA(1).valB(2).build();
//some code
delete obj;
return 0;
}
[edit]
You can write another derived class with as many parameters as you want and still use a single 'build' method.
Add
using Builder::Build;
to the derived class's declarations. This will import this symbol into the derived class, and make both it, and the derived class methods, of the same name, available to overload resolution. I.e.
using Builder::Build;
void Build(int a);
I'm ignoring the fact that you can't construct the derived class anyway, since it fails to implement this pure virtual function from the base class.
Derived class override their functions from the one which has same parameters and same return value.
So if you declare a function like...
class Builder
{
public:
virtual void Build() = 0;
};
class ConcreteBuilder1 : public Builder
{
public:
void Build(int a);
};
class ConcreteBuilder2 : public Builder
{
public:
void Build(int a. struct A* a);
};
Here, Build function in ConcreteBuilder1 class treated as a new function, not override function.
So try this.
class Builder
{
public:
virtual void Build(int a, A* b = 0) = 0;
};
class ConcreteBuilder1 : public Builder
{
public:
void Build(int a);
};
class ConcreteBuilder2 : public Builder
{
public:
void Build(int a, struct A* a);
};
I wish it's helpful for you.
If I want to use inheritance to avoid repeating the common_method method below
int A::different_method()
{ return 1; }
int A::common_method()
{ return this->different_method()+1; }
int B::different_method()
{ return 2; }
int B::common_method()
{ return this->different_method()+1; }
what is the best way to do it?
One way is to make A and B inherit from a base class C, with the new methods:
int A::different_method()
{ return 1; }
int B::different_method()
{ return 2; }
int C::different_method()
{ return 0; }
int C::common_method()
{ return this->different_method()+1; }
but it is a little bit annoying that I have to also define the useless C::different_method. What is the best practice for such situations?
Try using pure virtual function:
struct Base {
virtual int different_method() = 0;
int common_method() {
return different_method() + 1;
}
};
struct Derived1 : Base {
int different_method() override {
return 1;
}
};
struct Derived2 : Base {
int different_method() override {
return 2;
}
};
Check it out live
One way is to make A and B inherit from a base class C,
Yes, you would need a base class C
class C {
public:
virtual ~C() { }
virtual int different_method() = 0;
virtual int C::common_method() {
return this->different_method()+1;
}
}
class A: public C {
// Implement
int different_method() override;
};
class B: public C {
int different_method() override;
};
If you just need to use the class A and B, you can declare your C class as abstract and implement only the common_method(). The different_method() can be declared in header file of C class as pure virtual function in this way:
virtual different_method()=0
I leave you a useful link for the pure virtual function and the abstract class
Are you really tied to the A a; a.common_method() syntax?
Why not
template <typename T>
int common_free_function(T& t) {
return t.different_method() + 1;
}
A a;
B b;
common_free_function(a);
common_free_function(b);
I am grappling with a problem on mocking using gmock. The simplified example below depicts it. I have public member functions in a class, that neither return any values nor take anything as inputs. They only change some private variables in the class. There is a third method that uses the effects of those 2 methods in order to calculate something (say, p) before spitting out the result to the outside world. I need to know how to mock update_a() and update_b() properly. To some extent I can mock them. But I just do not know how to associate some "actions" with their mock versions so that by invoking them I can generate some effects on the private variables. Here is what I have so far:
class MyClass {
private:
int a,
int b,
int p;
public:
MyClass() : a{}, b{}, p{} {}
void update_a() {
a += 2;
}
void update_b() {
b += 5;
}
int calculate_p() {
update_a();
update_b();
p = a * 100 + b * 50; // Just some random math making use of a and b.
return p;
}
}
class MockMyClass :public MyClass {
public:
MOCK_METHOD(void, update_a, (), (override));
MOCK_METHOD(void, update_b, (), (override));
int deletegate_to_real() {
return MyClass::calculate_p();
}
}
TEST(CalculatingP_Test, otherMemberFunctionsInvoked) {
MockMyClass mockob;
EXPECT_CALL(mockOb, update_a()).Times(1);
EXPECT_CALL(mockOb, update_b()).Times(1);
mockOb.delegate_to_real();
}
The test passes because the test only checks whether the mock versions of update_a() and update_b() are invoked. But, I am unable to get the mocked versions of update_a() and update_b() to do something that could directly modify a and b. Changing the private specifier to protected is one way I could think of. But wouldn't that compromise the design?
You can go further with your DIP:
struct IVarAB
{
virtual ~IVarAB() = default;
virtual void update_a() = 0;
virtual void update_b() = 0;
virtual int get_a() = 0;
virtual int get_b() = 0;
};
class VarAB : public IVarAB
{
int a = 0;
int b = 0;
public:
void update_a() override { a += 2; }
void update_b() override { b += 5; }
int get_a() override { return a; }
int get_b() override { return b; }
};
class MyClass {
private:
std::unique_ptr<IVarAB> varAB;
int p = 0;
public:
MyClass() : MyClass(std::make_unique<VarAB>()){}
explicit MyClass(std::unique_ptr<IVarAB> varAB) : varAB{std::move(varAB)} {}
void update_a() { varAB->update_a(); }
void update_b() { varAB->update_b(); }
int calculate_p() {
update_a();
update_b();
p = varAB->get_a() * 100
+ varAB->get_b() * 50; // Just some random math making use of a and b.
return p;
}
};
Then your mock can define return value for both a and b.
It was decided that I could proceed with replacing "private" with "protected". That solves all my problems.
class MockMyClass :public MyClass {
public:
MOCK_METHOD(void, update_a, (), (override));
MOCK_METHOD(void, update_b, (), (override));
void set_dummy_a(int arg_a) {a = arg_a;}
void set_dummy_b(int arg_b) {b = arg_b;}
int deletegate_to_real() {
return MyClass::calculate_p();
}
}
TEST(CalculatingP_Test, otherMemberFunctionsInvoked) {
MockMyClass mockob;
EXPECT_CALL(mockOb, update_a()).Times(1);
EXPECT_CALL(mockOb, update_b()).Times(1);
mockOb.delegate_to_real();
}
TEST(CalculatingP_Test, shouldCalculateP_basedon_a_and_b) {
MockMyClass mockob;
EXPECT_CALL(mockob, update_a()).WillRepeatedly([&mockob]()
{mockob.set_dummy_a(20000);});
EXPECT_CALL(mockob, update_b()).WillRepeatedly([&mockob]()
{mockob.set_dummy_b(20000);});
int expected {3000000};
EXPECT_EQ(expected, mockob.delegate_to_real());
}
as the code below made for example purposes in C #, I would have had to do in C ++, if so how do you do?
public class MyClassTest{
public int testint1{get;set;}
public MyClassTest2 classTest2{get;set;}
}
public class MyClassTest2{
public int testint2{get;set;}
public MyClassTest classTest{get;set;}
}
Something like this.
class MyClassTest {
private: // optional: C++ classes are private by default
int testint1;
public:
int getTestInt1() const { return testint1; }
void setTestInt1(int t) { testint1 = t; }
};
Or you could make your member name distinct and skip the get/set keywords:
class MyClassTest {
private:
int testint1_;
public:
int testint1() const { return testint1_; }
void testint1(int t) { testint1_ = t; }
};
There is no equivalent to this in the current C++ standard, you just have to create getter/setter methods for any fields you want:
class MyClass {
public:
MyClass() {}
// note const specifier indicates method guarantees
// no changes to class instance and noexcept specifier
// tells compiler that this method is no-throw guaranteed
int get_x() const noexcept { return x; }
void set_x(int _x) { x = _x; }
private:
int x;
};
In Visual Studio (mine is 2013), it could be done in this way:
__declspec(property(get = Get, put = Set)) bool Switch;
bool Get() { return m_bSwitch; }
void Set(bool val) { m_bSwitch = val; }
bool m_bSwitch;
in a Class.
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.