简体   繁体   English

googlemock如何在测试中使用mocking

[英]googlemock how to use mocking in test

I'm a beginner with google mock and I'm not sure how to use it and the concept.我是 google mock 的初学者,我不知道如何使用它和这个概念。

If I'm trying to Test a method from a class that is calling some other methods from different classes.如果我试图从 class 中测试一个方法,该方法正在从不同的类中调用一些其他方法。 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?我是否需要模拟测试我的测试方法所需的 class A 和 B 中的所有方法? Or can I just mock one Class, and test if this class is working.或者我可以只模拟一个 Class,然后测试这个 class 是否工作。

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). 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).然后你需要使用 BIface 的依赖注入到 C class (通过添加的ctor)。 Having that you will be able to test interactions of B and C classes.有了它,您将能够测试 B 和 C 类的交互。 IMO A class doesn't need to be mocked in CTest (but most probably need to be tested in BTest) IMO A class 不需要在 CTest 中进行模拟(但很可能需要在 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.我不是 100% 确定,但在您的示例中,您根本不必使用模拟。 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:当我希望调用某个方法并返回特定值时,我会使用模拟 - 我不是在测试这个方法,而是在测试 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));为了操纵如果会得到什么,我会使用这样的模拟: EXPECT_CALL(aMock.method()).WillOnce(Return(true)); But you can use it in many more situations (eg: you can avoid creating really big class and replace it with mock object).但是您可以在更多情况下使用它(例如:您可以避免创建非常大的 class 并将其替换为模拟对象)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM