반응형

의존성 추가

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.kotest.extensions:kotest-extensions-spring:1.1.3")
testImplementation("com.ninja-squad:springmockk:4.0.2") // for MockkBean

TestWebMvcConfig

@Configuration
class TestWebMvcConfig {
    @Bean
    fun mockMvc(context: WebApplicationContext, filters: List<Filter>): MockMvc {
        return MockMvcBuilders.webAppContextSetup(context)
            .addFilters<DefaultMockMvcBuilder>(*filters.toTypedArray()) // 설정한 Filter들 MockMvc에도 설정(빈으로 등록되지 않은 Filter라면 직접 생성해서 세팅 필요)
            .defaultResponseCharacterEncoding<DefaultMockMvcBuilder>(StandardCharsets.UTF_8) // 응답 한글 깨짐 방지 설정
            .build()
    }
}

MessageService

@Service
class MessageService {
    fun getMessage() = "Hello World"
}

NowService

@Service
class NowService {
    fun getNow() = LocalDateTime.now()
}

DemoController

@RestController
class DemoController(
    private val messageService: MessageService,
    private val nowService: NowService,
) {
    @GetMapping("/api/v1/message")
    fun getMessage() = messageService.getMessage()

    @GetMapping("/api/v1/now")
    fun getNow() = nowService.getNow()
}

DemoControllerTest

@ContextConfiguration(classes = [DemoApplication::class])
@ActiveProfiles("test")
@AutoConfigureMockMvc
@SpringBootTest
class DemoControllerTest(
    private val mockMvc: MockMvc,
    @MockkBean
    private val messageService: MessageService,
) : FunSpec({
    listeners(ConstantNowTestListener(LocalDateTime.parse("2023-01-01 00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))))

    context("GET /api/v1/message") {
        every { messageService.getMessage() } returns "TEST"

        test("정상 응답 테스트") {
            val result = mockMvc
                .get("/api/v1/message") {
                    contentType = MediaType.APPLICATION_JSON
                }
                .andReturn()

            result.response.status shouldBe HttpServletResponse.SC_OK
            result.response.contentAsString shouldBe "TEST"
        }
    }

    context("GET /api/v1/now") {
        test("정상 응답 테스트") {
            val result = mockMvc
                .get("/api/v1/now") {
                    contentType = MediaType.APPLICATION_JSON
                }
                .andReturn()

            result.response.status shouldBe HttpServletResponse.SC_OK
            result.response.contentAsString shouldBe "\"2023-01-01T00:00:00\""
        }
    }
})

properties 설정

@SpringBootTest(
    properties = ["spring.profiles.active=local"]
)
class DemoTest(
    @Value("\${spring.profiles.active}")
    private val profile: String,
) : FunSpec({
    test("properties 테스트") {
        profile shouldBe "local"
    }
})

AutoConfiguration 설정하기 및 설정제외하기

@EnableAutoConfiguration( // 전체 AutoConfiguration 설정
    exclude = [KafkaAutoConfiguration::class], // 특정 AutoConfiguration 제외 설정
)
@SpringBootTest
class DemoTest : FunSpec({
    test("테스트") {
        // kafka 자동 설정으로 인한 로그가 발생하지 않는 현상 확인
    }
})

Bean 등록하기 및 등록제외하기

@ComponentScan(
    basePackages = [
        "com.example.demo", // 하위 패키지의 Bean을 모두 등록
    ],
    excludeFilters = [
        ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = [DemoApplication::class]), // 특정 타입의 Bean 등록 제외
        ComponentScan.Filter(type = FilterType.REGEX, pattern = ["com.example.demo.demo2.(.*)"]), // 특정 패키지 경로의 Bean 등록 제외
    ]
)
class TestApplication
@SpringBootTest(classes = [TestApplication::class])
class DemoTest : FunSpec({
    test("테스트") {
    }
})
반응형

'Development > Kotest' 카테고리의 다른 글

[Kotest] mockk  (0) 2023.11.04
[Kotest] Testcontainers  (0) 2023.11.04
[Kotest] extensions  (0) 2023.11.04
[Kotest] lifecycle hook  (0) 2023.11.04
[Kotest] isolation modes  (0) 2023.11.04

+ Recent posts