簡體   English   中英

googlemock如何在測試中使用mocking

[英]googlemock how to use mocking in test

我是 google mock 的初學者,我不知道如何使用它和這個概念。

如果我試圖從 class 中測試一個方法,該方法正在從不同的類中調用一些其他方法。 我是否需要從我的測試方法正在調用的不同類中模擬所有這些方法。 這是一個例子:


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;        
};

我是否需要模擬測試我的測試方法所需的 class A 和 B 中的所有方法? 或者我可以只模擬一個 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). 然后你需要使用 BIface 的依賴注入到 C class (通過添加的ctor)。 有了它,您將能夠測試 B 和 C 類的交互。 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));
}

我不是 100% 確定,但在您的示例中,您根本不必使用模擬。 您可以在這里非常輕松地創建對象。

當我希望調用某個方法並返回特定值時,我會使用模擬 - 我不是在測試這個方法,而是在測試 if-statment:

 A a;
 if(a.method())
 { 
      // some logic 
 }
  • 為了操縱如果會得到什么,我會使用這樣的模擬: EXPECT_CALL(aMock.method()).WillOnce(Return(true)); 但是您可以在更多情況下使用它(例如:您可以避免創建非常大的 class 並將其替換為模擬對象)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM