C++ GoogleTest의 gMock 사용하여 유닛테스트 작성하기 (UnitTest)

|

gMock이란?

https://github.com/google/googletest/blob/master/googlemock/README.md

구글에서 만든 유닛테스트를 위한 Mocking 라이브러리이다.
구글테스트를 처음 접한다면 이 블로그의 Google Test 사용하기 를 먼저 읽고 Mocking을 해보는것을 권한다.

유닛테스트를 작성할 때는 외부 디펜던시를 차단하고 테스트해야 한다. 이때 외부에서 주입받은 클래스를 가짜로 만드는것이 Mocking하는 것이다.

더 상세한 정보는 아래에 있다.

먼저 Mocking을 하기 전에 Mocking할 대상을 상속받는 클래스를 만들어야 한다.

#include "gmock/gmock.h"

class MockFoo : public Foo {
  ...
  MOCK_METHOD(int, GetSize, (), (const, override));
  MOCK_METHOD(string, Describe, (const char* name), (override));
  MOCK_METHOD(string, Describe, (int type), (override));
  MOCK_METHOD(bool, Process, (Bar elem, int count), (override));
};

하지만 이는 번거로운 일이다. 이를 위해 제너레이터가 파이썬 스크립트로 이미 작성되어 있다.

{구글테스트 폴더}/googlemock/scripts/generator 에 가면, gmock_gn.py가 존재한다. python3 gmock_gn.py 명령어를 통해 실행하고, 변경하고 싶은 클래스의 절대경로를 입력하면 모킹클래스를 자동으로 출력해준다. 이를 사용하면 된다.

이제 Mocking 클래스를 사용해보자.

using ::testing::Return;                          // #1

TEST(BarTest, DoesThis) {
  MockFoo foo;                                    // #2

  ON_CALL(foo, GetSize())                         // #3
      .WillByDefault(Return(1));
  // ... other default actions ...

  EXPECT_CALL(foo, Describe(5))                   // #4
      .Times(3)
}         

위 코드에서 EXPECT_CALL이란 Mocking class의 메소드 호출이 기대된다는 뜻이다. 따라서 위 코드에서는 foo의 Describe 함수가 호출되야 테스트가 성공한다.

또한 Times(3)의 의미는 foo의 Describe 함수가 3번 호출되어야 한다는 것을 뜻한다. 이를 잘 활용하면 외부에서 주입받은 클래스를 모킹하고 예상되는 행위 호출을 통해 클래스를 테스트할 수 있다.

ON_CALL은 Mocking class가 테스트용으로 만든 가짜 클래스이기 때문에 특정한 함수가 불렸을 때의 행동을 정의하는 것이다. 위의 예제에서 ON_CALL(foo, GetSize()).WillByDefault(Return(1))의 의미는 foo에서 GetSize()가 불렸을 때 1을 리턴하게 한다는 뜻이다.

gMock Test Suite를 작성할때 주의할 점은, EXPECT_CALL을 실제 함수를 부르기 전에 정의해두어야 한다.