Github Action - CI

깃허브에서 제공하는 CI/CD 툴이다. 공식홈페이지에 아주 자세한 설명이 나와있다. 사용방법은 매우 쉽다. 하고 싶은 작업과 조건들을 스크립트에 작성만 해주면 된다. 스크립트 템플릿도 바로 깃헙에서 만들 수 있다. 거기서 원하는 부분만 고쳐서 쓰면 된다. 일단 내 목적은 테스트 통과, build 통과였다. 자동생성된 템플릿에서 자바 버젼을 수정해주고 테스트를 추가해준다.

      - name: Set up JDK 19
        uses: actions/setup-java@v1
        with:
          java-version: 19

      - name: run tests
        run: ./gradlew test

이렇게 처음 테스트를 실행할 때 ./gradlew 실행이 실패했다. 원인은 접근권한이 없다는 것.

그래서 권한 부여 커맨드를 스텝에 추가해주었다.

      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: chmod +x gradlew

깃헙에서 제공하는 가상머신 위에서 동작하기 때문에 매번 실행해주어야 할 것 같다. 공식 문서에 따르면 직접 자신의 runner를 호스팅할 수도 있다고 한다.

빌드가 잘 된다.

Mockk

mockito보다 코틀린에 더 적합하다고 평가받는 mocking 라이브러리다. 스프링 공식 가이드문서에 나온다. 위의 예시대로 스프링 환경에서 지원되는 버젼이 있어서 kotest와 섞어서 써보려고 했는데.. 잘 안된다.. 어디가 문젠지 모르겠다. 내일 다시 해봐야겠다.

@WebMvcTest(ProposeController::class)
@AutoConfigureMockMvc
class ProposeUpdateTestGpt(@Autowired val mockMvc: MockMvc) : FunSpec() {

    @MockkBean
    private lateinit var service: ProposeService

    init {
        beforeTest {
            service = mockk()
            every { service.createFundingProposal(any()) } returns FundingProposal(1L, "제안서 제목")
            every { service.updateFundingProposal(any(), any()) } returns FundingProposal(1L, "새로운 제안서 제목")
        }

        test("제안서 생성") {
            val expectedId = 1L
            val expectedTitle = "제안서 제목"

            mockMvc.perform(post("/fundMng/proposal/create")
                .content("제안서 제목")
                .contentType("text/plain")
            ).andExpect(status().isOk)
                .andExpect(jsonPath("$.id").value(expectedId))
                .andExpect(jsonPath("$.title").value(expectedTitle))
        }

        test("제안서 수정") {
            val proposalId = 1
            val newTitle = "새로운 제안서 제목"
            val expectedId = 1L
            val expectedTitle = "새로운 제안서 제목"

            mockMvc.perform(put("/fundMng/proposal/1")
                .content(newTitle)
                .contentType("text/plain")
            ).andExpect(status().isOk)
                .andExpect(jsonPath("$.id").value(expectedId))
                .andExpect(jsonPath("$.title").value(expectedTitle))
        }
    }
}