Goolge Mock(gmock)

YB Lee·2023년 6월 23일
0

googletest

목록 보기
2/4

Mock 사용 이유

  • Object가 비결정적 결과를 return할 때 (현재 시간, 온도 등)
  • Object가 재현 또는 구현하기 힘든 상태를 가질 때 (network error)
  • Object의 동작이 느릴 때 (Test 전에 초기화 되어야 하는 DB)
  • Object를 아직 구현하지 않았거나 동작이 바뀌었을 때
  • Test를 위한 method나 information을 포함해야 할 때 등등

https://www.youtube.com/watch?v=dLB2aDasVTg&list=PL_dsdStdDXbo-zApdWB5XiF2aWpsqzV55&index=4

예시

#include <iostream>
#include <vector>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
 
using namespace std;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::_;
 
class DataBaseConect{
 
public:
    virtual bool login(string username, string password) { return true; }
    virtual bool logout(string username) { return true; }
    virtual int fetchRecord() { return -1; }
 
};
 
class MockDB : public DataBaseConect {
public:
    MOCK_METHOD0(fetchRecord, int());
    MOCK_METHOD1(logout, bool (string username));
    MOCK_METHOD2(login, bool (string username, string password));
}
 
class MyDatabase {
    DataBaseConect & dbc;
public:
    MyDatabase(DataBaseConect & _dbc) : dbc(_dbc) {}
    int Init(string username, string password){
        if(dbc.login(username, password) != true) {
            cout << "DB FAILURE" << endl; return -1;
        } else {
            cout << "DB SUCCES" << endl; return -1;
        }
    }
}
 
TEST(MyDBTest, LoginTest) {
    //Arange
    MockDB mdb;
    MyDatabase db(mdb);
    EXPECT_CALL(mdb, login("yb", "qwer1234"))
    .Times(1)
    .WillOnce(Return(true));
     
    //Act
    int retValue = db.Init("yb", "qwer1234");
    
    //Assert
    EXPECT_EQ(retValue, 1);
 
}
 
int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

예시 코드 개요

  • 테스트하고자 하는 component: MyDatabase
  • 외부 인터페이스: MyDatabase
  • Mock: MockDB

EXPECT_CALL

EXPECT_CALL이란 Mocking class의 메소드 호출이 기대한다는 뜻이다. 아래의 코드의 의미는

EXPECT_CALL(mdb, login("yb", "qwer1234")) .Times(1) .WillOnce(Return(true));

메소드 login 메소드가 ("yb", "qwer1234") 를 파라미터를 받았을 때, 한번 호출을 기대하며 한번 호출시 true를 리턴하는 것을 의미.

만약 두번이상 login이 호출되면 테스트는 fail 이 되며, ("yb", "qwer1234") 가 아닌 다른 파라미터를 입력받을 경우 true를 리턴하지 않는다.

ON_CALL

위의 EXPECT_CALL 을 아래와 같이 변경하는 경우

...

ON_CALL(mbd, login(_, _)).WillByDefault(Return(**true**));

...


ON_CALL 은 특정함수가 호출되었을때 행동을 정의하는 것으로, 위의 예제일 경우 login 이 호출될 때마다 항상 default로 true 를 리턴하도록 할 수 있다.

(여기서 파라미터 _ 는 아무 파라미터 값이 입력되어도 괜찮다는 의미)

MOCK_METHOD0(), MOCK_METHOD1(), MOCK_METHOD2()

=> 파라미터가 0개 1개 2개 의미

예를 들어 MOCK_METHOD2(login, bool (string username, string password)); 를 분석해보면

새롭게 선언하는 MOCK_METHOD인 login 함수는 리턴 형태가 boolean 이며 입력받는 파라미터는 2개이고 (string username, string password) 와 같음을 의미

그외 주요 매크로 Invoke, AtLeast,

Invoke() → EXPECT_CALL(), ON_CALL() 은 MOCK_METHOD에 대해 특정 파라미터가 주어질 시 특정 리턴 값을 세팅할 수 있는 매크로. 따라서 실제 해당 함수는 실행되지 않는다.

경우에 따라 함수가 실제로 내부 로직이 수행되어야 할 경우 Invoke 사용.

AtLeast() 는 EXPECT_CALL 의 Times() 함수안에 선언될 수 있으며, EXPECT_CALL(mdb, login("yb", "qwer1234")) .Times(AtLeast(1)); 이렇게 입력시

login 은 최소 한번이상 호출되어야 하며 그 이하로 호출시 테스트 fail 이 됨.

예시 코드 (위 코드에서 아래부분만 변경)

ORIGINAL LOGIN... 이 출력된 것을 확인할 수 있다.

profile
Those who have a 'why' to live, can bear with almost any 'how'.

0개의 댓글