🐥

SpringBootで使用するアノテーション(JUnit編)

2024/07/26に公開

Spring BootとJUnitは、JavaやKotlinでの迅速で強力なテスト環境を提供します。Spring Bootは、アプリケーション全体を自動的に設定し、JUnitは単体テストと統合テストを実行するためのフレームワークです。これらのツールを組み合わせることで、効率的にテストを行うことができます。以下に、Spring BootとJUnitでよく使用されるアノテーションとその具体例をKotlinで紹介します。

1. @SpringBootTest

@SpringBootTestは、Spring Bootアプリケーションの完全なコンテキストをロードして統合テストを実行するためのアノテーションです。このアノテーションを使用すると、実際のアプリケーションと同様の環境でテストを行うことができます。

import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
class ApplicationTests {

    @Test
    fun contextLoads() {
        // コンテキストが正常にロードされることを確認するテスト
    }
}

2. @Test

@Testは、JUnitの基本的なアノテーションで、テストメソッドを示します。このアノテーションを付けることで、そのメソッドがテストとして実行されます。

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class ExampleTests {

    @Test
    fun additionTest() {
        val sum = 1 + 1
        assertEquals(2, sum)
    }
}

3. @MockBean

@MockBeanは、SpringのコンテキストにモックのBeanを注入するためのアノテーションです。これにより、依存するサービスやコンポーネントのモックをテストに使用できます。

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean

@SpringBootTest
class GreetingServiceTests {

    @MockBean
    lateinit var greetingService: GreetingService

    @Autowired
    lateinit var greetingController: GreetingController

    @Test
    fun testGreet() {
        given(greetingService.greet("Kotlin")).willReturn("Hello, Kotlin")

        val result = greetingController.greet("Kotlin")
        assertEquals("Hello, Kotlin", result)
    }
}

4. @Autowired

@Autowiredは、Springの依存性注入機能を使用してBeanを自動的にインジェクションするためのアノテーションです。テストクラスでも使用され、必要なBeanを注入します。

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
class AutowiredTests {

    @Autowired
    lateinit var greetingService: GreetingService

    @Test
    fun testGreet() {
        val result = greetingService.greet("Kotlin")
        assertEquals("Hello, Kotlin", result)
    }
}

5. @TestConfiguration

@TestConfigurationは、テスト用の特定の設定を提供するためのアノテーションです。通常の@Configurationクラスの代わりに使用し、テスト用のBean定義を行います。

import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean

@TestConfiguration
class TestConfig {

    @Bean
    fun testGreetingService(): GreetingService {
        return GreetingService("Test Greeting")
    }
}

6. @ExtendWith

@ExtendWithは、JUnit 5の拡張機能を追加するためのアノテーションです。Spring Bootのテストでよく使用される拡張機能には、SpringExtensionがあります。これにより、SpringのコンテキストをJUnit 5のテストで使用できます。

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension

@ExtendWith(SpringExtension::class)
@SpringBootTest
class ExtensionTests {

    @Autowired
    lateinit var greetingService: GreetingService

    @Test
    fun testGreet() {
        val result = greetingService.greet("Kotlin")
        assertEquals("Hello, Kotlin", result)
    }
}

7. @WebMvcTest

@WebMvcTestは、Spring MVCコンポーネント(コントローラー)に焦点を当てたテストを行うためのアノテーションです。このアノテーションを使用すると、コントローラーとその依存関係のみがロードされます。

import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers

@WebMvcTest(GreetingController::class)
class WebMvcTests {

    @Autowired
    lateinit var mockMvc: MockMvc

    @MockBean
    lateinit var greetingService: GreetingService

    @Test
    fun testGreet() {
        given(greetingService.greet("Kotlin")).willReturn("Hello, Kotlin")

        mockMvc.perform(MockMvcRequestBuilders.get("/greet").param("name", "Kotlin"))
            .andExpect(MockMvcResultMatchers.status().isOk)
            .andExpect(MockMvcResultMatchers.content().string("Hello, Kotlin"))
    }
}

8. @DataJpaTest

@DataJpaTestは、JPAコンポーネント(リポジトリ)に焦点を当てたテストを行うためのアノテーションです。このアノテーションを使用すると、データベースアクセスを伴うテストが簡単に行えます。

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest

@DataJpaTest
class UserRepositoryTests {

    @Autowired
    lateinit var userRepository: UserRepository

    @Test
    fun testSaveAndFindUser() {
        val user = User(name = "John Doe")
        userRepository.save(user)

        val foundUser = userRepository.findById(user.id!!)
        assertEquals("John Doe", foundUser.get().name)
    }
}

9. @Transactional

@Transactionalは、トランザクション管理を行うためのアノテーションです。このアノテーションをテストメソッドやクラスに付けることで、そのメソッド内で行われるデータベース操作がトランザクション内で実行されます。

import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.transaction.annotation.Transactional

@SpringBootTest
class TransactionalTests {

    @Autowired
    lateinit var userRepository: UserRepository

    @Test
    @Transactional
    fun testTransactional() {
        val user = User(name = "John Doe")
        userRepository.save(user)

        val foundUser = userRepository.findById(user.id!!)
        assertEquals("John Doe", foundUser.get().name)
    }
}

10. @Rollback

@Rollbackは、テスト後にデータベースの状態を元に戻すためのアノテーションです。@Transactionalと組み合わせて使用されることが多いです。

import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.annotation.Rollback
import org.springframework.transaction.annotation.Transactional

@SpringBootTest
class RollbackTests {

    @Autowired
    lateinit var userRepository: UserRepository

    @Test
    @Transactional
    @Rollback
    fun testRollback() {
        val user = User(name = "John Doe")
        userRepository.save(user)

        val foundUser = userRepository.findById(user.id!!)
        assertEquals("John Doe", foundUser.get().name)
    }
}

11. @BeforeEachと@AfterEach

@BeforeEachは、各テストメソッドの実行前に実行されるメソッドを示します。@AfterEachは、各テストメソッドの実行後に実行されるメソッドを示します。

import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test

class LifecycleTests {

    @BeforeEach
    fun setup() {
        // テスト前のセットアップ
    }

    @AfterEach
    fun teardown() {
        // テスト後のクリーンアップ
    }

    @Test
    fun testSomething() {
        // テスト内容
    }
}

12. @Disabled

@Disabledは、特定のテストメソッドやクラスを無効にするためのアノテーションです。テストを一時的にスキップしたい場合に使用します。

import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test

class DisabledTests {

    @Test
    @Disabled("Disabled until bug #1234 is fixed")
    fun testDisabled() {
        // このテストは実行されません
    }
}

まとめ

Spring BootとJUnitの組み合わせにより、アプリケーションのさまざまなコンポーネントに対する強力なテストが実現できます。これらのアノテーションを適切に使用することで、テストコードの記述が簡素化され、効率的なテストが可能となります。Kotlinでの具体例を通じて、各アノテーションの使用方法とその役割を理解することができます。これにより、堅牢で保守性の高いコードを実現することができます。

Discussion