2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【研修備忘録】Spring Boot 開発&テストでよく使ったアノテーション・メソッドまとめ

2
Posted at

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

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?