Open6

【SOLID原則】#3 "依存性逆転の原則(dependency inversion principle)"の勉強会後の振り返り

ピン留めされたアイテム
阿部耕二阿部耕二

このページは何?

2023/9/28(木)に実施する社内勉強会、X スペース 【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則(dependency inversion principle)"

  • 気づき
  • 感想
  • 質問
  • より良い設計の案(いやいや私だったらこう設計するよ、その理由はxxだから)
  • その他

などイベント後の振り返り、学びを深めるために作成しました。ぜひ、自分以外の設計の視点を得るために有効活用してください。

勉強会資料(speakerdeck)はこちらです。

リンクが有効な資料はこちらです。
https://www.docswell.com/s/juraruming/5EN9ME-2023-09-28-065704

投稿ルール

  • クソコードを憎んで人を憎まず、個人に対しての誹謗中傷の書き込みはやめてください。
  • より良い設計の案を提示いただける場合、なぜそのような設計が良いのか お手数ですが理由を書いてください。それが読む人に非常に価値のある学びになります。
阿部耕二阿部耕二

より良い設計の案

阿部耕二阿部耕二

依存性注入のテストの改善

資料の依存性注入のテストは使い勝手がよくない。読み込みデータ異常のテストをする際は異常な読み込みデータをセットするモックを追加する必要がある。

CppUMockを使ったテストに変更してみる。
モックのSettingValueMockクラスのreadメソッドを任意のint型の戻り値を返せるようにする。

SettingValueMock.cpp
#include "SettingValueMock.h"

#include <iostream>
using namespace std;

#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

// コンストラクタの実装
SettingValueMock::SettingValueMock() {
    cout << "SettingValueMock constructor" << endl;
}

SettingValueMock::~SettingValueMock() {
    cout << "SettingValueMock decstructor" << endl;
}

void SettingValueMock::write() {
}

int SettingValueMock::read() {
    return mock().actualCall("read").returnIntValue();
//    return 100;
}

テストコード側はつぎのようにする。

SettingValueExampleTest.cpp
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

#include <iostream>
using namespace std;
#include "SettingValueValidation.h"
#include "SettingValueMock.h"
#include "ISettingValue.h"

TEST_GROUP(SettingValueExampleTest)
{
    SettingValueValidation* settingValueValidation;

    void setup()
    {
      settingValueValidation = new SettingValueValidation(new SettingValueMock());
    }

    void teardown()
    {
      mock().clear();
      delete settingValueValidation;
    }
};

TEST(SettingValueExampleTest, SettingValueinValid)
{
  mock().expectOneCall("read").andReturnValue(99);

  CHECK_FALSE(settingValueValidation->validate());
}

TEST(SettingValueExampleTest, SettingValueValid)
{
  mock().expectOneCall("read").andReturnValue(100);

  CHECK(settingValueValidation->validate());
}

テストの意図はつぎのとおり。

  • SettingValueValidテストは読み込みチェックOKを期待するテスト(読み込みデータは100以上)
  • SettingValueinValidテストは読み込みチェックNGを期待するテスト(読み込みデータは100未満)

実行結果はつぎのとおり(余計なprint文は削除している)。

$ ./bin/dip_and_di_test_easy_env -v
TEST(SettingValueExampleTest, SettingValueValid)
 - 0 ms
TEST(SettingValueExampleTest, SettingValueinValid)
 - 0 ms

OK (2 tests, 2 ran, 6 checks, 0 ignored, 0 filtered out, 1 ms)

モックと依存性注入でテストしやすくなった。