Spring Boot 開発&テストでよく使ったアノテーション・メソッドまとめ
新人エンジニアが研修のアプリケーション開発を経て(真っ最中)、よく見るけどよくわからんといったアノテーションやメソッドについて備忘録としてまとめました。
本記事で扱う内容↓
・verify
・assertion
・@Autowired
・@Transactional
・@GetMapping
・@PostMapping
〇verifyメソッド
verify は Mockito でモックのメソッドが呼ばれたかを確認するためのものです。
__
検証対象:メソッドの呼び出し自体
エラーメッセージ:メソッド呼び出しの不一致を報告
使用場面:ふるまいの検証
__
メソッドの戻り値だけでなく、呼び出しタイミングや回数、可否、順序が重要な時などに不可欠なメソッドです。
verifyメソッドの基本構文
times(n):呼び出し回数を指定する
never():呼び出されていないことを確認
atLeastOnce():最低1回の呼び出しを確認
atMost(n):最大n回までの呼び出しを確認
〇assertメソッド
assertXxx は JUnit や AssertJ で、処理結果が期待どおりかを確認するためのものです。
__
検証対象:メソッドの戻り値や状態
エラーメッセージ:値の不一致を報告
使用場面:結果の検証
__
各Assertメソッド
assertEquals:数値、文字列、オブジェクトなど、期待値と実際の値を比較して一致しているか
assertTrue/False:真偽値やブール式など条件式の検証
assertNull/NotNull:null値の検証
assertThrows:例外の発生有無や種類の検証
assertAll:複数検証を一括実行
assertArrayEquals:要素の順序も含めた配列を比較
具体例↓
class OrderTest {
@Test
void testCheckout() {
// 準備:ダミーの決済オブジェクトを作成
Payment mockPayment = mock(Payment.class);
Order order = new Order(mockPayment);
// 実行
order.checkout();
// 検証:
// 1. verify(ふるまいの検証)
// payment.pay() が「1回」呼ばれたかを確認
verify(mockPayment, times(1)).pay();
// 2. assert(結果の検証)
// 何らかのステータスが期待通りかを確認(ここではtrueを想定)
assertTrue(order.isProcessed());
}
}
参考:https://dexall.co.jp/articles/?p=605#i-2
〇@AutowiredとDI
依存性注入(DI:Dependency Injection)するアノテーション。
依存性注入:クラスが必要とするオブジェクトを自動的に注入する。new演算子を使った手動でのインスタンス化が不要になる。
DIなし例とDIあり例
DIなしの場合↓
class Order {
// 内部で特定クラス(CreditCard)を直に生成
private CreditCard payment = new CreditCard();
public void checkout() {
payment.pay();
}
}
// 使う側
Order order = new Order(); // Orderの中でクレカが自動で固定作成される
order.checkout();
DIありの場合↓
class Order {
private Payment payment;
// どの決済を使うかは外から注入してもらう=OrderがPaymentに依存
public Order(Payment payment) {
this.payment = payment;
}
public void checkout() {
payment.pay();
}
}
// 使う側
Payment payment = new CreditCard(); // 1. 外で決済を用意して
Order order = new Order(payment); // 2. Order に注入する!
order.checkout();
DIなしの場合:
たとえば...
「PayPay決済も使いたい」→ Orderクラスの中身を直接書き換えなくてはいけない。バグのもと!
「Orderクラスの動作をテストしたい」→ 毎回本物のカード決済メソッドが動いてしまったりする。エラーのもと!
DIありの場合:
たとえば...
「PayPay決済も使いたい」→ Orderクラスの中身は書き直す必要なし。新しくPayPayクラスを作って、外からOrderに渡せば動く。
「Orderクラスの動作をテストしたい」→ 成功したふりをするダミーの決済クラス(Mock)を外から注入できるので安全にテスト可能。
具体例
// Springの管理対象にする目印(@Component)
@Component
public class CreditCard implements Payment {
public void pay() {
System.out.println("クレジットカードで決済しました。");
}
}
@Component
public class Order {
private final Payment payment;
// Springが自動で CreditCard インスタンスを探してここに渡してくれる
@Autowired
public Order(Payment payment) {
this.payment = payment;
}
public void checkout() {
payment.pay(); // 自動注入されているのでそのまま使える
}
}
注入を受ける側に@Autowiredをつけることで、Springが「Payment」の実装クラス(CreditCard)を自動で探して注入してくれる。
結論:
「注文」と「決済」の役割がきちんと分かれていると、Orderを改造することなく、Paymentのパーツを自由に交換したり追加、修正できてメンテナンスがしやすくなります。
参考:https://dexall.co.jp/articles/?p=347
〇@Transactional
複数のDB操作をひとまとまりの処理として扱うためのアノテーション。
・DBへの登録
・更新
・削除
などの処理を行ったとき、一連の流れの中で例外が発生(送出)すると、それまでの操作を取り消して元の状態に戻します(ロールバック)。
※ただメソッド内で try-catch を行い、例外をキャッチしたまま握りつぶしてしまうと、Spring は処理が正常終了したと判断し、ロールバックされずに DB にコミットされてしまいます。
発生した例外の種類によってデフォルトの挙動が変わります。
デフォルトでロールバックされる場合:
・RuntimeException(非チェック例外:NullPointerException や IllegalArgumentException など)
・Error(システムレベルの重大なエラー)
デフォルトではロールバックされない場合:
・チェック例外(Exception のうち RuntimeException を継承していないもの:IOException や SQLException など)
チェック例外でもロールバックしたいときは、
rollbackFor = Exception.classをつけます。
@Transactional(rollbackFor = Exception.class)
public void doSomething() throws Exception {
...
}
@Transactionalの具体例↓
@Transactional
public void updateUser() {
userRepository.save(user1);
userRepository.save(user2);
}
このとき、
・user1の保存
・user2の保存
を一つのまとまりとして扱います。仮にuser2の保存が失敗したら、user1の保存含めそれまでの処理が取り消されます。
参考:https://dexall.co.jp/articles/?p=347
〇@GetMappingと@PostMapping
@GetMapping
webページを表示する際に使用するSpringBootのアノテーション。
HTTPのGETメソッドを受け取る。おもに取得処理担当。
・一覧を表示する
・詳細を表示する
・検索する
・画面を開いたときにデータを取得する
@PostMapping
ユーザーがフォームに入力した情報をサーバーに送信して DBに保存したりする。
HTTPのPOSTメソッドを受け取る。おもに新規登録(リソースの作成)やデータの送信担当。
・新規登録
・フォーム送信
・ログイン
・データ保存
※データはリクエストボディに含まれ、URLに表示されませんが、データが暗号化・非表示化されて安全になるわけではありません。個人情報やログイン認証情報などの機密データを扱う際は、POST を使うだけでなく以下のようなシステム全体の設計が不可欠です。
HTTPS(TLS/SSL)の導入: 通信経路自体を暗号化し、盗聴や改ざんを防止する。
ログ設計: リクエストボディの内容がサーバーログやアクセスログに平文で記録されないよう制御する。
アクセス制御: 認証・認可(Spring Security など)を導入し、不正アクセスやなりすましを防ぐ。
比較まとめ
| 項目 | @GetMapping | @PostMapping |
|---|---|---|
| 主な用途 | データの取得 | データの送信・新規登録 |
| データの扱い | 画面表示や検索でよく使う | DB保存や更新でよく使う |
| URLにデータが見えるか | 表示される | 表示されない |
| 再実行の影響 | 比較的少ない | 登録が重複することがある |
| 例 | 一覧表示、詳細表示 | 新規登録、ログイン |
参考:
https://dexall.co.jp/articles/?p=347
https://dexall.co.jp/articles/?p=605#i-2
https://qiita.com/NagaokaKenichi/items/a279857cc2d22a35d0dd
https://spring-boot.jp/mvc/controller/19