main関数をテストしたい基地外な人のためのメモ ~クラス編~

もう main関数 とか関係無いけど。

残念な人なので、今日はこんなコードに当たりました。

// main.cpp
#include <stdio.h>
#include "hoge.h"

int main(int argc, char* argv[])
{
  Hoge hoge("hoge hoge");

  return (hoge() != 0);
}

昨日より短いですね!!

今回の場合

さて、今日はこれを頑張ってやってみました。

テストコード

では、今日も一気に。

// test_main.cpp

// 元のコードの無効化
#include "hoge.h"
#undef Hoge

// モックに切り替え
#define Hoge mock_Hoge

// google test
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using ::testing::Return;

// モック
struct mock_Hoge
{
  mock_Hoge(const char* str){}
  int operator()() { return mock.apply_internal(); }

  struct _inner_mock {
    MOCK_METHOD0(apply_internal, int());
  };
  static _inner_mock mock;
};
mock_Hoge::_inner_mock mock_Hoge::mock;

// 元のコードの取り込み
// (中略)

// テスト
TEST(main_function, fail_hoge)
{
  // hoge() は1回だけ呼ばれて 0 を返すよ
  EXPECT_CALL(mock_Hoge::mock, apply_internal())
    .Times(1)
    .WillRepeatedly(Return(0));

  // 実行結果は 0 だよ、たぶん
  EXPECT_EQ(0, _old_main(0, NULL));
}

// テストコード用エントリーポイント
// (中略)

EXPECT_CALL()にはテストで実際に使用されるインスタンスが必要なので、モック用Hogeクラスにクラス変数を持たせて、それを外部から操作することで、モックの振る舞いを記述するようにしました。

なんか、不毛なことをしてる気がする・・・