1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

テストが書きづらくなる設計の正体

Posted at

テストが書きづらくなる設計の正体

— 壊れにくい設計は、テストが先に楽になる —

はじめに

ここまでの連載で、こんな話をしてきました。

  • DI(依存性注入)
  • Service層の役割
  • EntityとDTOの分離
  • トランザクションの境界
  • Repositoryの責務

これらは一見、別々の設計ルールに見えます。

しかし実は、
すべて「テストの書きやすさ」に収束します。

今回は、

なぜこの設計だとテストが楽で、
逆だと地獄になるのか

を整理して、連載を締めます。


まず「テストが書きづらいコード」を思い出す

ありがちな例です。

  • Controllerにロジックがある
  • Entityをそのまま@RequestBodyで受ける
  • Repositoryに業務判断がある
  • あちこちに@Transactional

この状態でテストを書こうとすると、こうなります。

  • MockMvcが必要
  • DBが必要
  • SpringContextが必要
  • 設定が多すぎる

テストしたいのは業務ルールなのに、
周辺準備が9割

これは偶然ではありません。


テストが重い = 責務が混ざっている

テストが書きづらいとき、
だいたい次のことが起きています。

  • 業務ロジックとI/Oが混ざっている
  • 境界が曖昧
  • 依存関係が固定されている

つまり、

設計の歪みが、テストにそのまま現れている

状態です。

テストは設計のレントゲン写真みたいなものです。


ここまでの設計がどう効いてくるか

DI(依存性注入)

DIがあると、

UserService service = new UserService(mockRepository);

が書けます。

  • 差し替え可能
  • モック可能
  • 単体で確認可能

「Springを起動しないテスト」が書けるのは、
DIのおかげです。


Service層の分離

Serviceにロジックが集まっていると、

service.register(name);

だけをテストできます。

  • HTTPなし
  • JSONなし
  • Controllerなし

業務ルールだけに集中できます。


EntityとDTOの分離

DTOを使っていると、

  • 入力の形
  • 永続化の形

を別々に扱えます。

その結果、

  • 入力バリデーションのテスト
  • 業務ロジックのテスト

を分離できます。

Entityを直接触らなくて済むのは、
テストでも大きなメリットです。


トランザクションをServiceで切る

Serviceに@Transactionalがあると、

  • 処理の単位
  • 成功/失敗の境界

が明確になります。

テストでも、

  • ここまで成功
  • ここで例外

という期待値が見える。

「どこまでが一連か」が見えない設計は、
テストでも迷子になります。


Repositoryの責務を絞る

Repositoryが「取得と保存」に徹していると、

  • RepositoryはDB前提のテスト
  • Serviceは業務ルールのテスト

粒度を分けられます

全部Repositoryにあると、
全部DBテストになります。

これは避けたい。


良い設計のサイン

設計がうまくいっていると、
こんなことが起きます。

  • テストコードが自然に書ける
  • モックの数が少ない
  • Springを起動しないテストが多い

逆に、

「テストが面倒だから書かない」

は、設計の黄色信号です。


テストは目的ではなく、結果

誤解されがちですが、

テストを書くために設計するわけではありません

しかし、

良い設計の結果として、テストが楽になる

これはほぼ例外がありません。

  • 責務が分かれている
  • 境界が明確
  • 依存が注入されている

この状態が、
そのままテストの書きやすさになります。


まとめ(連載の結論)

この連載で伝えたかったことを、一言で言います。

Springの設計は、全部つながっている

DI、Service、DTO、Transaction、Repository。
どれか1つだけ守っても意味は薄い。

でも全部そろうと、

  • 変更に強い
  • 理解しやすい
  • テストしやすい

という「長く生き残るコード」になります。


おわりに

JavaやSpringは、
「とりあえず動く」までは簡単です。

でも、

動き続けるコードを書く

には、設計が必要です。

この連載が、
「なぜそう書くのか」を考える
きっかけになっていれば嬉しいです。

ここまで読んでくれて、ありがとうございました。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?