第8章スプリングテスト

7503 ワード

ユニットテスト:テストするクラスの実装のみをテストします.テストするクラスに依存する他のコンポーネントをmockまたはstubとして作成し、テスト対象クラスの実行結果が他のコンポーネントの実行内容の影響を受けないようにします.
統合テスト:首やスタブではなく、実際の操作環境で使用されるクラスを統合してテストします.スプリングテストを使用して統合テストを行うのは、システム全体またはアプリケーションが予想通りに正しく動作しているかどうかを検証するのではなく、開発者が作成したクラスがスプリングフレームワークで正しく動作しているかどうかを検証します.
スプリングテストは主に以下の機能を提供します.
  • JUnitは、テストフレーム(TestNGと呼ぶ)を使用してスプリング上のDI容器を駆動する機能
  • である.
  • トランザクション制御機能
  • アプリケーションサーバなしでSpring MVCの動作を再現できる
  • SQLを実行して
  • のテストデータをロードする機能
  • RestTemplateを使用してHTTP要求にランダム応答を送信する技術
  • .
    DI容器と空白テスト
    DIコンテナで管理されている空(@Controller、@Service、@Repository、@Componentなどのクラスがある)のメソッドをテストします.
    JUnit依存の追加
    空の単位のテスト
    スプリングを使用しないDI容器機能は,試験対象クラスで実現したロジックのみをテストする
    public class MessageServiceTest {
        @Test
        public void testGetMessage() {
            MessageService service = new MessageService();
            String actualMessage = service.getMessage();
            assertThat(actualMessage, is("Hello!!"));
        }
    }
    メッセージ・サービスは、内部的にメッセージ・ソースに依存します.
    ユニットテスト環境では、Mockitoシミュレーションメッセージソースを使用してテストを行います.
    org.mockito.mockito-core依存項目を追加します.
    @RunWith(MockitoJUnitRunner.class)
    public class MessageServiceTest {
        @InjectMock
        MessageService service;
        
        @Mock
        MessageSource mockMessageSource;
        
        @Test
        public void testGetMessageByCode() {
            doReturn("Hello!!").when(mockMessageSource)
                .getMessage("greeting", null, Locale.getDefault());
            
            String actualMessage = service.getMessageByCode("greeting");
            assertThat(actualMessage, is("Hello!!"));
        }
    }
    DIコンテナで管理されている空の統合テスト
    スプリングDI容器に登録した後、他の素子に集積した場合のさらなる試験を行った.
    データベースなどの外部リソースへのアクセスをテストすることが望ましい.便利な外部システムまたは外部サイトに関連する部分は、MockまたはStubで置き換えることができる.
    @RunWith(SpringJUnit4ClassRunner.class) // DI컨테이너를 동작시키기 위한 Runner클래스 지정. 스프링 4.3부터 SpringJUnit4ClassRunner 별칭 클래스 SpringRunner 클래스 존재
    @ContextConfiguration(class = AppConfig.class) // classes 속성에 DI 컨테이너가 사용하는 설정 클래스를 지정
    public class MessageServiceIntegrationTest {
        @Autowired
        MessageService messageService; // DI컨테이너의 빈 인젝션
        
        @Test
        public void testGetMessageByCode() {
            String actualMessage = service.getMessageByCode("greeting");
            assertThat(actualMessage, is("Hello!!"));
        }
    }
    Spring TestContextフレームワーク
    テスト用スプリングフレームのテストフレームでの機能.
    springが提供するプレゼンテーション、Java標準プレゼンテーション、springテストが提供するテスト原稿などを使用して、テストケースを作成できます.
    SpringJUnit 4 ClassRunner(SpringRunner)クラスは、SpringTestContextフレームワークを実行するJUnitのサポートクラスです.@RunWithに割り当てられたvalueプロパティ(*@RunWithではRunnerクラスは1つしか指定できません.Mockitoが提供するRunnerクラスなどの他のRunnerクラスとは使用できません.他のRunnerをSpringTestContextフレームワークとともに使用するにはSpringClass/SpringMethodRuleを使用します.
    SpringTestContextフレームワークでDIコンテナを作成するには@orgを使用します.springframework.test.context.ContextConfigurationをテストケースに貼り付け、空の定義ファイルをプレゼンテーションのclassプロパティまたはlocationプロパティに割り当てます.
    @ContextConfiguration(classes = AppConfig.class)
    public class MessageServiceIntegrationTest {
        // ...
    }
    class属性またはlocation属性を省略した場合
    @RunWith(SpringRunner.class)
    @ContextConfiguration
    public class MessageServiceIntegrationTest {
        @Configuration
        static class LocalContext {
            // ...
        }
    }
    内部クラスによって定義された静的設定クラスの情報を使用します.
    Webアプリケーションのテスト環境設定
    @org.springframework.test.context.ContextConfiguration,@orgを構成しないでください.springframework.test.context.web.WebAppConfigurationを使う方法もあります.この方法を使用して、Webアプリケーション専用のDIコンテナ(WebApplicationContext)を作成します.
    @WebAppConfigurationを使用する場合、プロジェクトのsrc/main/webappディレクトリはWebアプリケーションのルートディレクトリとみなされます.これは、MavenまたはGreyが作成した標準Webアプリケーションのルートディレクトリと同じです.
    サーブレットAPIを使用するさまざまなターゲットオブジェクト(MockサーブレットContext、MockHttpSession、MockHttpサーブレットRequest、MockHttpサーブレットResponse)も、テストケースに注入できます.
    プロファイルの指定
    スプリングプロファイル機能を使用するアプリケーションは@ActiveProfilesを使用してテストします.
    テストの構成値の指定
    システム構成(JavaVMの-Dオプション)またはプロファイルからインポートされたクラスがある場合は、構成値を変更してテストする必要があります.
    @TestPropertySourceを使用します.
    Testクラスで
    プロパティ値は、@TestPropertySource(properties = "auth.failureCountToLock=3")または@TestPropertySource(locations = "/test.properties")を使用して指定できます.
    データベースのテスト
    データベースへのアクセスに必要な操作をテストします.
  • テストデータソース設定
  • テストデータマウント
  • テストケースのトランザクション制御
  • データ検証
  • テストデータソースの設定
    テスト用のデータ・ソース定義の例
    @Configuration
    public class TestConfig {
        @Bean
        public DataSource dataSource() { // 실제로 사용할 데이터 소스의 빈과 같은 이름을 사용
            return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .setScriptEncoding("UTF-8")
                .addScript("schema.sql")
                .build();
        }
    }
    @ContextConfiguration(classes = {AppConfig.class, TestConfig.class})
    public class AccountRepositoryTest {
        // ...
    }
    @ContextConfigurationで空の定義ファイルを指定する場合は、まず実際に使用する空の定義ファイルを指定し、次にテスト用の空の定義ファイルを指定します.
    データ・マウントのテスト
    @org.springframework.test.context.jdbc.sqlを使用します.
    テストケースのメソッドを呼び出す前に、SQLを任意に実行できます.SQLの実行時間をテストケースのメソッド終了後に変更できます.
    @Sqlをカスタマイズするには、configプロパティでSqlConfigを指定します.
    @Sqlはクラスとメソッドに適用できます.両方が適用される場合は、まずメソッドに適用されます.
    // ...
    @Sql("/account-delete.sql")
    public class AccountRepositoryTest {
        ...
        
        @Test // account-delete.sql이 실행된다.
        public void testCreate() {
            // ...
        }
        
        // account-delete.sql와 account-insert-data.sql 이 실행된다.
        @Test
        @Sql({"/account-delete.sql", "/account-insert-data.sql"})
        public void testFindOne() {
            // ...
        }
    }
    テストケースのトランザクションの管理
    複数のテスト環境で同じデータベースが共有されている場合、JUnitの実行中に別のテストでデータが変更される場合がありますので、特に注意が必要です.
    スプリングテストで提供されるテストトランザクション機能を使用して解決します.
    トランザクション境界の移動
    トランザクション境界をテストケースのメソッドに移動する前に、springで提供されている@Transactionalをクラスまたはメソッドに貼り付けるだけです.
    トランザクション境界でのロールバックとコミットの制御
    @Transactionalを使用してトランザクション境界をテストケースに移動する方法が実行される前に、デフォルトではテストの終了時にトランザクションがロールバックされます.
    コミットが必要な場合は@orgを使用します.springframework.test.annotation.クラスまたはメソッドにCommitを割り当てます.
    @Transactional
    @Commit // 클래스에 @Commit 지정
    public class AccountRepositoryTest {
        @Test // 커밋됨
        public void testCreate1() {
            // ...
        }
        
        @Test
        @Rollback // 롤백됨
        public void testCreate2() {
            // ...
        }
    }
    データ検証
    JdbcTemplateを使用して検証できます.
    たとえば、挿入されたデータが正しく挿入されているかどうかを確認するには、repositoryにデータを挿入し、挿入されたデータのキーを使用してJDbcTemplateを使用してデータベースで挿入したばかりのデータをクエリーし、クエリーされたデータの有効性を検証します.
    @Transactionalを使用する場合、JdbcTemplateで使用されるデータソースとテストコンポーネントで使用されるデータソースは同じである必要があります.
    スプリングMVCテスト
    コントローラのテストはSpring MVCフレームワーク機能を統合した統合テストと見なすことができる.
    従来の方法は、Webアプリケーションをアプリケーションサーバに配備し、E 2 Eを使用してテストすることです.次のような欠点があります.
  • アプリケーションサーバまたはデータベース
  • を実行する必要があります.
  • トランザクションがコミットされたため、テスト前のステータス
  • に戻ることはできません.
  • 回帰試験を行うためには,Selenium等を用いて試験用例を実現する必要がある.
  • スプリングテストは、E 2 Eテストの欠点を解消し、スプリングMVCと統合されたコントローラをテストすることを目的としている.springframework.test.web.servlet.MockMvcクラスを提供します.
    MockMvc
    サーバのクラスにWebアプリケーションを配備することなくSpring MVCの動作を再現できます.
    潮流
    1.テストケースのメソッドは、DispatcherServiceletを要求するデータ(要求パスや要求パラメータなど)を設定します.
    2.MockMvcはDispatcherServiceletに要求を送信する.この時点で使用するDispatcherServeretは、テスト用のorgを拡張します.springframework.test.web.servlet.TestDispatcherServlet
    3.DispatcherSellvetは要求を受信し、マッピング情報を表示し、対応するHandlerメソッドを呼び出す.
    4.テストケースメソッドは、MockMvcから返された実行結果を受信し、実行結果が正しいことを確認します.