34
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

新卒が「テスタブルなコード」について本気出して考えてみた

Last updated at Posted at 2025-05-13

はじめに

こんにちは!
新卒2年目(そろそろ言い訳できなくなってくる時期)のエンジニアです。


コードレビューでいろんなご指摘を頂くのですが、
その中でも特に指摘されたのが、、

• 「DIに従って」

• 「これだと単体テスト書けないよ!」

でした。
いわゆるテスタブルなコードにしようって話ですね。

DI…??単体テスト…???
っていう混乱状態から始まった自分が、ちょっとだけわかるようになってきたのでまとめてみました。
お手柔らかに....:sweat:

テスタブルなコードってなんだ?

テストが書きやすいコード! です。

なるほど....(????)

自分は調べてこうなりました(笑)

実際の例を見てみましょうー!

テストしにくいコード(やりがち)

class UserService {
    public function register(string $email) {
        $user_dao = new UserDao(); // ← ここでnewしてる
        $user_dao->save($email);
    }
}

学生の時はひたすらこれでした笑
一見だいじょぶそう。でも問題が!!

  1. 依存
    →UserServiceがUserDaoの実装に依存してしまっているので、単体テストができない
  2. DB接続してしまう
    →実際にDB接続してしまうため、単体テストができない

ノットテスタブルですね。


じゃあ、テスタブルなコードにするには?

キーワードは DI(Dependency Injection) です。

なんか必殺技みたいで強そう()

簡単に説明すると、
「newは外でやって、それを渡す」
それだけ!それだけ!

DIを考慮して書き直してみると、、

class UserService {
    private $user_dao;
    
    public function __construct(UserDao $user_dao) {
        $this->user_dao = $user_dao;
    }

    public function register(string $email) {
        $this->user_dao->save($email);
    }
}

これでテスタブルなコード、単体テストが書けるようになりました!!!!

(.......)
なんでこれだと単体テストが書けるようになるんだ??
当時の自分はここでもピンと来ませんでした。


もう少し詳しく話します。

上記のようなコードにすることで、UserService は UserDao を直接インスタンス化する必要がなくなり、代わりに UserDao 型のもの(モック)を外部から渡すことができるようになりました!
なので単体テストが書けるように!!

いや待て、モックってなんだよ...

簡単に言うと、
単体テストで使う、指定したクラスを抽象化した偽物のこと!

実際にモックを使って単体テストを書いてみると...

    //Mockery使用
    // モックを作成
    $mock_user_dao = Mockery::mock('UserDao');
    // 期待する呼び出し内容を指定
    $mock_user_dao->shouldReceive('save')
        ->once()
        ->with('test@example.com');
    // テスト対象のサービスを生成
    $service = new UserService($mock_user_dao);
    // メソッドを実行
    $service->register('test@example.com');

処理の説明は割愛しますが、
上記のようにUserDaoの偽物を実際に単体テストをしたいUserServiceに渡してあげることで、他に依存しない、UserServiceだけの単体テストができるというわけです。

単体テストをするメリット

1.コードを個別にテストすることで、バグの早期発見ができる!
2.リファクタリングした際、既存の処理が壊れていないことを担保できる!
3.手動テストでの確認漏れを防げる!

すごい、これがテスタブルってやつか...

まとめ

「テスタブルなコード」って、最初はふわっとしててよく分からない言葉でしたが、
実はとてもシンプルでした!

• newは外でやって渡す(=DI)
• モックを使えば、依存先を偽物に置き換えてテストできる
→ だから単体テストが書ける!

単体テストが書けるコードにすると、
バグを早く見つけられるし、リファクタも安心してできるし、何より怖くなくなる!
これが少しずつ実感できてきたなと思います。

コードレビューの指摘も少しずつ減ってきた……気がします!
これからもがんばります!

34
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?