🎁[속보] 인프런 내 깜짝 선물 출현 중🎁

[인프런 워밍업 클럽 3기] 백엔드 발자국 2주차

[인프런 워밍업 클럽 3기] 백엔드 발자국 2주차

📒 2주차에 배운 내용

📌 Controller, Service , Repository , DTO 개발과 테스팅, 그리고 Tymeleaf fragments 에 대해 학습하는 시간이였다.

강의 중에 다뤘던 PresentationService 테스트


@DisplayName("활성화된 Introduction 만 조회하는데 성공한다. ")
@Test
fun testGetIntroductions() {/* given */
    val introductions = mutableListOf<Introduction>()
    (1..DATA_SIZE).forEach {
        introductions.add(Introduction(content = "$it", isActive = it % 2 == 0))
    }

    val activeIntroductions = introductions.filter { it.isActive }

    Mockito.`when`(presentationRepository.getActiveIntroductions()).thenReturn(activeIntroductions)

    /* when */
    val introductionDTOs = presentationService.getIntroductions()

    /* then */
    assertThat(introductionDTOs).hasSize(DATA_SIZE / 2)
    introductionDTOs.forEach {
        assertThat(it.content.toInt()).isEven()
    }
}

 

@DisplayName("활성화된 Link 만 조회하는데 성공한다. ")
@Test
fun testGetLinks() {/* given */
    val links = mutableListOf<Link>()
    (1..DATA_SIZE).forEach {
        links.add(Link(name = "$it", content = "$it", isActive = it % 2 != 0))
    }

    val activeLinks = links.filter { it.isActive }

    Mockito.`when`(presentationRepository.getActiveLinks()).thenReturn(activeLinks)

    /* when */
    val linkDTOs = presentationService.getLinks()

    /* then */
    var expectedSize = DATA_SIZE / 2
    if (DATA_SIZE % 2 != 0) expectedSize += 1
    assertThat(linkDTOs).hasSize(expectedSize)
    linkDTOs.forEach {
        assertThat(it.content.toInt()).isOdd()
    }
}

 

Repository 성능 개선 -> N + 1 해결하기 (fetch join)

@Repository
interface ProjectRepository: JpaRepository<Project, Long> {
    @Query("select distinct p from Project p left join fetch p.details where p.id = :id")
    override fun findById(id: Long): Optional<Project>
}

📌 JPQL fetch Join

spring:
  application:
    name: kotlin-portfolio
  jpa:
    database: h2
    open-in-view: false
    show-sql: true
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        format_sql: true
        default_batch_fetch_size: 10 # batch size 조절 

📌`application.yml` 에서 batch size 설정

 

Mocking 을 활용한 Controller 테스트

val logger = KotlinLogging.logger {}
@AutoConfigureMockMvc
@SpringBootTest
@DisplayName("[API 컨트롤러 테스트]")
class PresentationApiControllerTest (
    @Autowired private val mockMvc: MockMvc,
){
    @DisplayName("Introductions 조회")
    @Test
    fun testGetIntroductions() {
        /* given */
        val uri = "/api/v1/introductions"

        /* when */
        val mvcResult = performGet(uri)
        val contentAsString = mvcResult.response.contentAsString
        val jsonArray = JSONArray(contentAsString)

        /* then */
        assertThat(jsonArray.length()).isPositive()
    }

    @DisplayName("Links 조회")
    @Test
    fun testGetLinks() {
        /* given */
        val uri = "/api/v1/links"

        /* when */
        val mvcResult = performGet(uri)
        val contentAsString = mvcResult.response.contentAsString
        val jsonArray = JSONArray(contentAsString)

        /* then */
        assertThat(jsonArray.length()).isPositive()
    }

    @DisplayName("Resume 조회")
    @Test
    fun testGetResume() {
        /* given */
        val uri = "/api/v1/resume"

        /* when */
        val mvcResult = performGet(uri)
        val contentAsString = mvcResult.response.contentAsString
        val jsonObject = JSONObject(contentAsString)

        /* then */
        logger.info{jsonObject.optJSONObject("experiences")}
        assertThat(jsonObject.optJSONArray("experiences").length()).isPositive()
        assertThat(jsonObject.optJSONArray("achievements").length()).isPositive()
        assertThat(jsonObject.optJSONArray("skills").length()).isPositive()
    }


    private fun performGet(uri: String): MvcResult {
        return mockMvc
            .perform (MockMvcRequestBuilders.get(uri))
            .andDo(MockMvcResultHandlers.print())
            .andReturn()
    }
}



📌 2주차 미션

  • 1 대 다 관계를 갖는 테이블 설계하기

  • Rest API 를 설계하기

댓글을 작성해보세요.


채널톡 아이콘