From 6f877803442383ccc2c400712ac5175de25d23b8 Mon Sep 17 00:00:00 2001 From: pricelees Date: Tue, 15 Jul 2025 16:13:27 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=83=88=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98=ED=95=9C=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20=EB=B0=94=ED=83=95?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20AuthControllerTest=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomescape/auth/web/AuthControllerTest.kt | 137 ++++++++++++------ 1 file changed, 93 insertions(+), 44 deletions(-) diff --git a/src/test/java/roomescape/auth/web/AuthControllerTest.kt b/src/test/java/roomescape/auth/web/AuthControllerTest.kt index 0f23f160..a4f575d1 100644 --- a/src/test/java/roomescape/auth/web/AuthControllerTest.kt +++ b/src/test/java/roomescape/auth/web/AuthControllerTest.kt @@ -1,23 +1,34 @@ package roomescape.auth.web +import com.ninjasquad.springmockk.SpykBean import io.mockk.every import org.hamcrest.Matchers.containsString -import org.hamcrest.Matchers.`is` +import org.hamcrest.Matchers.equalTo +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest import org.springframework.data.repository.findByIdOrNull +import org.springframework.test.web.servlet.MockMvc +import roomescape.auth.service.AuthService import roomescape.common.exception.ErrorType import roomescape.util.MemberFixture import roomescape.util.RoomescapeApiTest -class AuthControllerTest : RoomescapeApiTest() { +@WebMvcTest(controllers = [AuthController::class]) +class AuthControllerTest( + @Autowired mockMvc: MockMvc +) : RoomescapeApiTest() { + + @SpykBean + private lateinit var authService: AuthService val userRequest: LoginRequest = MemberFixture.userLoginRequest() init { Given("로그인 요청을 보낼 때") { - val endpoint: String = "/login" + val endpoint = "/login" When("로그인에 성공하면") { - val expectedToken: String = "expectedToken" + val expectedToken = "expectedToken" every { memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password) @@ -28,12 +39,19 @@ class AuthControllerTest : RoomescapeApiTest() { } returns expectedToken Then("토큰을 쿠키에 담아 응답한다") { - runPostTest(endpoint, body = MemberFixture.userLoginRequest()) { - statusCode(200) - cookie("accessToken", expectedToken) - header("Set-Cookie", containsString("Max-Age=1800")) - header("Set-Cookie", containsString("HttpOnly")) - header("Set-Cookie", containsString("Secure")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = userRequest, + log = true + ) { + status { isOk() } + header { + string("Set-Cookie", containsString("accessToken=$expectedToken")) + string("Set-Cookie", containsString("Max-Age=1800")) + string("Set-Cookie", containsString("HttpOnly")) + string("Set-Cookie", containsString("Secure")) + } } } } @@ -44,10 +62,14 @@ class AuthControllerTest : RoomescapeApiTest() { } returns null Then("400 에러를 응답한다") { - runPostTest(endpoint, body = userRequest) { - log().all() - statusCode(400) - body("errorType", `is`(ErrorType.MEMBER_NOT_FOUND.name)) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = userRequest, + log = true + ) { + status { isBadRequest() } + jsonPath("$.errorType", equalTo(ErrorType.MEMBER_NOT_FOUND.name)) } } } @@ -57,36 +79,47 @@ class AuthControllerTest : RoomescapeApiTest() { Then("이메일 형식이 잘못된 경우") { val invalidRequest: LoginRequest = userRequest.copy(email = "invalid") - runPostTest(endpoint, body = invalidRequest) { - log().all() - statusCode(400) - body("message", `is`("이메일 형식이 일치하지 않습니다. 예시: abc123@gmail.com")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = invalidRequest, + log = true + ) { + status { isBadRequest() } + jsonPath("$.message", containsString("이메일 형식이 일치하지 않습니다.")) } } Then("비밀번호가 공백인 경우") { val invalidRequest = userRequest.copy(password = " ") - runPostTest(endpoint, body = invalidRequest) { - log().all() - statusCode(400) - body("message", `is`("비밀번호는 공백일 수 없습니다.")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + body = invalidRequest, + log = true + ) { + status { isBadRequest() } + jsonPath("$.message", containsString("비밀번호는 공백일 수 없습니다.")) } } } } Given("로그인 상태를 확인할 때") { - val endpoint: String = "/login/check" + val endpoint = "/login/check" When("로그인된 회원의 ID로 요청하면") { - every { jwtHandler.getMemberIdFromToken(any()) } returns user.id!! - every { memberRepository.findByIdOrNull(user.id!!) } returns user + loginAsUser() Then("회원의 이름을 응답한다") { - runGetTest(endpoint) { - statusCode(200) - body("data.name", `is`(user.name)) + runGetTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { isOk() } + jsonPath("$.data.name", equalTo(user.name)) } } } @@ -98,39 +131,55 @@ class AuthControllerTest : RoomescapeApiTest() { every { memberRepository.findByIdOrNull(invalidMemberId) } returns null Then("400 에러를 응답한다.") { - runGetTest(endpoint) { - statusCode(400) - body("errorType", `is`(ErrorType.MEMBER_NOT_FOUND.name)) + runGetTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { isBadRequest() } + jsonPath("$.errorType", equalTo(ErrorType.MEMBER_NOT_FOUND.name)) } } } } Given("로그아웃 요청을 보낼 때") { - val endpoint: String = "/logout" + val endpoint = "/logout" When("로그인 상태가 아니라면") { - setUpNotLoggedIn() + doNotLogin() Then("로그인 페이지로 이동한다.") { - runPostTest(endpoint) { - log().all() - statusCode(302) - header("Location", containsString("/login")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { is3xxRedirection() } + header { + string("Location", "/login") + } } } } When("로그인 상태라면") { - setUpUser() - every { memberRepository.findByIdOrNull(user.id!!) } returns user + loginAsUser() Then("토큰의 존재 여부와 무관하게 토큰을 만료시킨다.") { - runPostTest(endpoint) { - log().all() - statusCode(200) - cookie("accessToken", "") - header("Set-Cookie", containsString("Max-Age=0")) + runPostTest( + mockMvc = mockMvc, + endpoint = endpoint, + log = true + ) { + status { isOk() } + header { + string("Set-Cookie", containsString("Max-Age=0")) + string("Set-Cookie", containsString("accessToken=")) + string("Set-Cookie", containsString("Path=/")) + string("Set-Cookie", containsString("HttpOnly")) + string("Set-Cookie", containsString("Secure")) + } } } }