SpringBootでテストコードを作成する


関連内容は、李棟旭。著書『Spring BootとAWSによる個別Webサービス』を勉強してまとめたもの.

TDDはユニットテストとは異なります。


TDD:まずテスト主導の開発→テストコードを作成する
  • は、常に失敗したテスト(Red)
  • を先に作成します.
  • テストに合格した生産コード(グリーン)
  • を作成する
  • 試験に合格すると、生産コードは再包装(Refactor)
  • される.
    ユニットテスト:TDDの最初のステップである機能ユニットのテストコードを記述します.
    まずテストコードを記述する必要はなく、テストコードを再記述する必要もありません.
    純粋な目的のテストコード
    まずユニットテストに慣れると、TDD学習に注目しなければなりません!

    なぜユニットテストを行うのですか?

  • の開発段階の初期に問題の発見を支援した.
  • 開発者は、後続のコード再構築またはライブラリアップグレードで既存の機能が正常に動作しているかどうかを確認できます.
  • 機能に対する不確実性を低減する.
  • システムの実際のドキュメントを提供することにより、ドキュメントとして使用することができる.
  • アプリケーションクラス

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
    
    @SpringBootApplication  
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    将来作成するプロジェクトの主なクラス

    @SpringBootApplication

  • スプリングガイドの自動設定、スプリングbeanの読み取りと作成は自動的に設定されます.
  • 対応の説明がある位置から設定の読み取りを開始するため、常にプロジェクトの最上位に位置する必要があります.
  • SpringApplication.run(Application.class, args)

  • スプリングガイド内蔵WASを実行します.
  • Tomcatを使用しても構いませんが、いつでもどこでも同じ環境でスプリングガイドを配置できるので、内蔵WASを使用することをお勧めします.
  • HelloController

    import com.shawn.springboot.web.dto.HelloResponseDto;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    
        @GetMapping("/hello")
        public String hello(){
            return "hello";
        }
    
        @GetMapping("/hello/dto")
        public HelloResponseDto helloDto(@RequestParam("name") String name
                                        , @RequestParam("amount") int amount){
            return new HelloResponseDto(name, amount);
        }
    }

    @RestController

  • コントローラをJSONに戻るコントローラにします.
  • がすべての方法で@ResponseBodyを宣言したように.
  • @RequestParam(「apiから渡されたデータの名前値」)String name

  • 外部からAPIに渡されるパラメータを取得する方法.
  • を超えるname値を受け入れ、宣言されたタイプに変換して変数名として保存します.
  • に対応する追加パラメータがない場合、400エラーが発生します.
  • パラメータが必須でない場合、@RequestParam(value="name"、required=false)String name
  • 必須でないパラメータの値がNullの場合、Nullの基本タイプを割り当てることができないとエラーが発生します.

    HelloControllerTest

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    
    import static org.hamcrest.Matchers.is;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
    
    @RunWith(SpringRunner.class)
    @WebMvcTest(controllers = HelloController.class) 
    public class HelloControllerTest{
    
        @Autowired
        private MockMvc mvc;
    
        @Test
        public void hello가_리턴된다() throws Exception {
            String hello = "hello";
    
            mvc.perform(get("/hello"))
                    .andExpect(status().isOk())
                    .andExpect(content().string(hello));
        }
    
        @Test
        public void helloDto가_리턴된다() throws Exception{
            String name = "hello";
            int amount = 32;
    
            mvc.perform(get("/hello/dto")
                    .param("name", name)
                    .param("amount", String.valueOf(amount)))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.name", is(name)))
                    .andExpect(jsonPath("$.amount", is(amount)));
        }
    }
    HelloControllerをテストするクラス

    @RunWith(SpringRunner.class)

  • のテストでは、JUnitに内蔵されている実行者のほか、他の実行者も割り当てられます.
  • では、SpringRunnerというスプリングアクチュエータをパラメータとして動作させる.
    スプリング起動テストとJUnitの間で接続者として機能します.
  • @WebMvcTest

  • Web(Spring MVC)
    宣言
  • の場合、@Controller、@Controller Addiceなどを使用できます.
  • セグメント、@Service、@Component、@Repositoryなどは使用できません.→JPA機能が機能しない
  • 上記の場合はコントローラのみを使用するため、
  • を使用する.

    private MockMvc mvc

  • Web APIのテストに使用します.
  • スプリングMVC試験起点
  • は、このクラスを通じてHTTP GET、POSTなどのAPIテストを行うことができる.
  • mvc.perform(get(”/hello”))


    GET要求は
  • MockMvcを介して/helloアドレスに送信される.
  • スクリーニングをサポートし、その後、複数の検証機能を宣言できます.

    .andExpect(status().isOk())

  • mvc.パラメータの内容でperformの結果を検証します.
  • HTTPヘッダの状態がOKであることを確認します(200).
  • .andExpect(content().string(hello))

  • が本明細書の内容が「hello」であるかどうかを確認します.
  • .param(”name”, value)

  • APIで使用する要求パラメータ設定
  • Stringのみ許可されます.
  • .andExpect(jsonPath("$.name", is(name)))


    フィールドにより
  • JSON応答値を検証する方法
  • "$.フィールド名".is(value)
  • HelloResponseDTO

    import lombok.Getter;
    import lombok.RequiredArgsConstructor;
    
    @Getter
    @RequiredArgsConstructor
    public class HelloResponseDto {
        private final String name;
        private final int amount;
    
    }

    @Getter / @Setter — Lombok


    すべての宣言フィールドを作成するget/setメソッド

    @RequiredArgsConstructor — Lombok


    すべての宣言を含むfinalフィールドを作成するジェネレータ
  • finalのないフィールドはジェネレータに含まれません.
  • @AllArgsConstructor / @NoArgsConstructor — Lombok

  • は、すべてのフィールド/パラメータを含むジェネレータ
  • を生成する.

    HelloResponseDTOTest

    import com.shawn.springboot.web.dto.HelloResponseDto;
    import org.junit.Test;
    
    import static org.assertj.core.api.Assertions.assertThat;
    
    public class HelloResponseDtoTest {
    
        @Test
        public void 롬복_기능_테스트(){
            //given
            String name = "test";
            int amount = 1000;
    
            //when
            HelloResponseDto dto = new HelloResponseDto(name, amount);
    
            //then
            assertThat(dto.getName()).isEqualTo(name);
            assertThat(dto.getAmount()).isEqualTo(amount);
        }
    }

    @assertThat — assertJ

  • で検証したいオブジェクトをメソッドパラメータとして取得します.
  • メソッドフィルタをサポートし、isEqualtoのようにメソッドを継続できます.
  • @isEqualTo — assertJ

  • 同等比較方法
  • assertThatのパラメータはisEqualtoのパラメータの値と比較され、同じ場合にのみ
  • に成功します.

    assertJはJUnitより優れている

  • JUnitのassertThatを使用する場合は、is()のようなCoreMatchersライブラリが必要ですが、assertJを使用する場合は追加のライブラリは必要ありません.
  • IDEではCoreMatchersのようなMatcherライブラリの自動完了サポートが弱い.