From b95423bec8b5f25bd2262c29a82e964027264d67 Mon Sep 17 00:00:00 2001 From: pricelees Date: Tue, 15 Jul 2025 16:12:42 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20\@SpringbootTest=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20mockk=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/roomescape/util/Fixtures.kt | 2 + .../java/roomescape/util/RoomescapeApiTest.kt | 104 +++++++++++------- 2 files changed, 64 insertions(+), 42 deletions(-) diff --git a/src/test/java/roomescape/util/Fixtures.kt b/src/test/java/roomescape/util/Fixtures.kt index d03b6fe5..4ae7a6b6 100644 --- a/src/test/java/roomescape/util/Fixtures.kt +++ b/src/test/java/roomescape/util/Fixtures.kt @@ -7,6 +7,8 @@ import roomescape.auth.web.LoginRequest import java.util.concurrent.atomic.AtomicLong object MemberFixture { + const val NOT_LOGGED_IN_USERID: Long = 0 + val idCounter: AtomicLong = AtomicLong(1L) fun create( diff --git a/src/test/java/roomescape/util/RoomescapeApiTest.kt b/src/test/java/roomescape/util/RoomescapeApiTest.kt index bd02bba7..23addfe6 100644 --- a/src/test/java/roomescape/util/RoomescapeApiTest.kt +++ b/src/test/java/roomescape/util/RoomescapeApiTest.kt @@ -1,30 +1,40 @@ package roomescape.util +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.ninjasquad.springmockk.MockkBean +import com.ninjasquad.springmockk.SpykBean import io.kotest.core.spec.style.BehaviorSpec import io.mockk.every -import io.restassured.http.ContentType -import io.restassured.module.kotlin.extensions.Given -import io.restassured.module.kotlin.extensions.Then -import io.restassured.module.kotlin.extensions.When -import io.restassured.response.ValidatableResponse -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.web.server.LocalServerPort import org.springframework.data.repository.findByIdOrNull +import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus -import roomescape.member.infrastructure.persistence.Member -import roomescape.member.infrastructure.persistence.MemberRepository +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.* import roomescape.auth.infrastructure.jwt.JwtHandler +import roomescape.auth.web.support.AdminInterceptor +import roomescape.auth.web.support.LoginInterceptor +import roomescape.auth.web.support.MemberIdResolver import roomescape.common.exception.ErrorType import roomescape.common.exception.RoomescapeException +import roomescape.member.business.MemberService +import roomescape.member.infrastructure.persistence.Member +import roomescape.member.infrastructure.persistence.MemberRepository +import roomescape.util.MemberFixture.NOT_LOGGED_IN_USERID -const val NOT_LOGGED_IN_USERID: Long = 0; +abstract class RoomescapeApiTest : BehaviorSpec() { -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@NoSqlInitialize -class RoomescapeApiTest( - @LocalServerPort val port: Int? = 9090, -) : BehaviorSpec() { + @SpykBean + private lateinit var AdminInterceptor: AdminInterceptor + + @SpykBean + private lateinit var loginInterceptor: LoginInterceptor + + @SpykBean + private lateinit var memberIdResolver: MemberIdResolver + + @SpykBean + lateinit var memberService: MemberService @MockkBean lateinit var memberRepository: MemberRepository @@ -32,36 +42,42 @@ class RoomescapeApiTest( @MockkBean lateinit var jwtHandler: JwtHandler - + val objectMapper: ObjectMapper = jacksonObjectMapper() val admin: Member = MemberFixture.admin() val user: Member = MemberFixture.user() - fun runGetTest(endpoint: String, token: String? = "token", assert: ValidatableResponse.() -> Unit): ValidatableResponse { - return Given { - port(port!!) - header("Cookie", "accessToken=$token") - } When { - get(endpoint) - } Then assert + fun runGetTest( + mockMvc: MockMvc, + endpoint: String, + log: Boolean = false, + assert: MockMvcResultMatchersDsl.() -> Unit + ): ResultActionsDsl = mockMvc.get(endpoint) { + header(HttpHeaders.COOKIE, "accessToken=token") + }.apply { + log.takeIf { it }?.let { this.andDo { print() } } + }.andExpect { + assert } fun runPostTest( + mockMvc: MockMvc, endpoint: String, - token: String? = "token", body: Any? = null, - assert: ValidatableResponse.() -> Unit - ): ValidatableResponse { - return Given { - port(port!!) - contentType(ContentType.JSON) - body?.let { body(it) } - header("Cookie", "accessToken=$token") - } When { - post(endpoint) - } Then assert + log: Boolean = false, + assert: MockMvcResultMatchersDsl.() -> Unit + ): ResultActionsDsl = mockMvc.post(endpoint) { + this.header(HttpHeaders.COOKIE, "accessToken=token") + body?.let { + this.contentType = MediaType.APPLICATION_JSON + this.content = objectMapper.writeValueAsString(it) + } + }.apply { + log.takeIf { it }?.let { this.andDo { print() } } + }.andExpect { + assert } - fun setUpAdmin() { + fun loginAsAdmin() { every { jwtHandler.getMemberIdFromToken(any()) } returns admin.id!! @@ -70,7 +86,7 @@ class RoomescapeApiTest( every { memberRepository.findByIdOrNull(admin.id!!) } returns admin } - fun setUpUser() { + fun loginAsUser() { every { jwtHandler.getMemberIdFromToken(any()) } returns user.id!! @@ -79,15 +95,19 @@ class RoomescapeApiTest( every { memberRepository.findByIdOrNull(user.id!!) } returns user } - fun setUpNotLoggedIn() { + fun doNotLogin() { every { jwtHandler.getMemberIdFromToken(any()) - } returns NOT_LOGGED_IN_USERID + } throws RoomescapeException(ErrorType.INVALID_TOKEN, HttpStatus.UNAUTHORIZED) - every { memberRepository.existsById(NOT_LOGGED_IN_USERID) } throws RoomescapeException( - ErrorType.LOGIN_REQUIRED, - HttpStatus.FORBIDDEN - ) + every { memberRepository.existsById(NOT_LOGGED_IN_USERID) } returns false every { memberRepository.findByIdOrNull(NOT_LOGGED_IN_USERID) } returns null } + + fun readValue(responseJson: String, valueType: Class): T = objectMapper + .readTree(responseJson)["data"] + ?.let { objectMapper.convertValue(it, valueType) } + ?: throw RuntimeException(""" + [Test] Exception occurred while reading response json: $responseJson with value type: $valueType + """.trimIndent()) }