관리 메뉴

피터의 개발이야기

[kotlin] Springboot - RestController 생성 및 WebMvcTest 본문

Programming/Kotlin

[kotlin] Springboot - RestController 생성 및 WebMvcTest

기록하는 백앤드개발자 2024. 5. 24. 10:10
반응형

ㅁ 들어가며

ㅇ spring boot tutorial를 참조하여 나만의 확장 프로그램 만들기를 구현해 보았습니다.

 

ㅁ RestController 생성

@RestController
@RequestMapping("/api/article")
class ArticleController(private val repository: ArticleRepository) {

  @GetMapping("/")
  fun findAll() = repository.findAllByOrderByAddedAtDesc()

  @GetMapping("/{slug}")
  fun findOne(@PathVariable slug: String) =
      repository.findBySlug(slug) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "This article does not exist")

}

@RestController
@RequestMapping("/api/user")
class UserController(private val repository: UserRepository) {

  @GetMapping("/")
  fun findAll() = repository.findAll()

  @GetMapping("/{login}")
  fun findOne(@PathVariable login: String) =
      repository.findByLogin(login) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "This user does not exist")
}

ㅇ 아티클의 목록과 상세 정보, 사용자의 목록과 상세 정보를 조회하는 API를 생성하였습니다.

 

ㅁ WebMvcTest를 위한 gradle 설정

// webMvcTest
testImplementation("org.springframework.boot:spring-boot-starter-test") {
    exclude(module = "mockito-core")
}
testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testImplementation("com.ninja-squad:springmockk:4.0.2")

ㅇ @MockBean주석은 Mockito에만 해당 되므로 Mockk에 유사한 주석을 제공하는 SpringMockK을 활용할 것입니다.

ㅇ build.gradle.kts에 테스트를 위한 의존성을 추가합니다.

 

ㅁ HttpControllersTests.kt 생성

@WebMvcTest
class HttpControllersTests(@Autowired val mockMvc: MockMvc) {

  @MockkBean
  lateinit var userRepository: UserRepository

  @MockkBean
  lateinit var articleRepository: ArticleRepository

  @Test
  fun `List articles`() {
    val johnDoe = User("johnDoe", "John", "Doe")
    val lorem5Article = Article("Lorem", "Lorem", "dolor sit amet", johnDoe)
    val ipsumArticle = Article("Ipsum", "Ipsum", "dolor sit amet", johnDoe)
    every { articleRepository.findAllByOrderByAddedAtDesc() } returns listOf(lorem5Article, ipsumArticle)
    mockMvc.perform(get("/api/article/").accept(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk)
        .andExpect(content().contentType(MediaType.APPLICATION_JSON))
        .andExpect(jsonPath("\$.[0].author.login").value(johnDoe.login))
        .andExpect(jsonPath("\$.[0].slug").value(lorem5Article.slug))
        .andExpect(jsonPath("\$.[1].author.login").value(johnDoe.login))
        .andExpect(jsonPath("\$.[1].slug").value(ipsumArticle.slug))
  }

  @Test
  fun `List users`() {
    val johnDoe = User("johnDoe", "John", "Doe")
    val janeDoe = User("janeDoe", "Jane", "Doe")
    every { userRepository.findAll() } returns listOf(johnDoe, janeDoe)
    mockMvc.perform(get("/api/user/").accept(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk)
        .andExpect(content().contentType(MediaType.APPLICATION_JSON))
        .andExpect(jsonPath("\$.[0].login").value(johnDoe.login))
        .andExpect(jsonPath("\$.[1].login").value(janeDoe.login))
  }
}

 

ㅇ 테스트가 정상적으로 작동하였다.

 

 

반응형
Comments