diff --git a/src/test/kotlin/roomescape/auth/web/AuthControllerTest.kt b/src/test/kotlin/roomescape/auth/web/AuthControllerTest.kt index e5e95461..aed2ee55 100644 --- a/src/test/kotlin/roomescape/auth/web/AuthControllerTest.kt +++ b/src/test/kotlin/roomescape/auth/web/AuthControllerTest.kt @@ -1,25 +1,24 @@ package roomescape.auth.web -import com.ninjasquad.springmockk.SpykBean +import com.ninjasquad.springmockk.MockkBean +import io.mockk.Runs import io.mockk.every +import io.mockk.just import org.hamcrest.Matchers.equalTo import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest import org.springframework.test.web.servlet.MockMvc import roomescape.auth.business.AuthService import roomescape.auth.exception.AuthErrorCode +import roomescape.auth.exception.AuthException import roomescape.common.exception.CommonErrorCode import roomescape.common.exception.ErrorCode -import roomescape.member.exception.MemberErrorCode -import roomescape.member.exception.MemberException import roomescape.util.MemberFixture import roomescape.util.RoomescapeApiTest @WebMvcTest(controllers = [AuthController::class]) -class AuthControllerTest( - val mockMvc: MockMvc -) : RoomescapeApiTest() { +class AuthControllerTest(val mockMvc: MockMvc) : RoomescapeApiTest() { - @SpykBean + @MockkBean private lateinit var authService: AuthService val userRequest: LoginRequest = MemberFixture.userLoginRequest() @@ -32,12 +31,8 @@ class AuthControllerTest( val expectedToken = "expectedToken" every { - memberFinder.findByEmailAndPassword(userRequest.email, userRequest.password) - } returns user - - every { - jwtHandler.createToken(user.id!!) - } returns expectedToken + authService.login(userRequest) + } returns LoginResponse(expectedToken) Then("토큰을 반환한다.") { runPostTest( @@ -52,12 +47,13 @@ class AuthControllerTest( } When("회원을 찾지 못하면") { + val expectedError = AuthErrorCode.LOGIN_FAILED + every { - memberFinder.findByEmailAndPassword(userRequest.email, userRequest.password) - } throws MemberException(MemberErrorCode.MEMBER_NOT_FOUND) + authService.login(userRequest) + } throws AuthException(expectedError) Then("에러 응답을 받는다.") { - val expectedError = AuthErrorCode.LOGIN_FAILED runPostTest( mockMvc = mockMvc, endpoint = endpoint, @@ -68,6 +64,7 @@ class AuthControllerTest( } } } + When("입력 값이 잘못되면") { val expectedErrorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE @@ -97,6 +94,10 @@ class AuthControllerTest( loginAsUser() Then("회원의 이름과 권한을 응답한다") { + every { + authService.checkLogin(user.id!!) + } returns LoginCheckResponse(user.name, user.role.name) + runGetTest( mockMvc = mockMvc, endpoint = endpoint, @@ -110,14 +111,12 @@ class AuthControllerTest( When("토큰은 있지만 회원을 찾을 수 없으면") { val invalidMemberId: Long = -1L + val expectedError = AuthErrorCode.MEMBER_NOT_FOUND every { jwtHandler.getMemberIdFromToken(any()) } returns invalidMemberId - every { - memberFinder.findById(invalidMemberId) - } throws MemberException(MemberErrorCode.MEMBER_NOT_FOUND) + every { authService.checkLogin(invalidMemberId) } throws AuthException(expectedError) Then("에러 응답을 받는다.") { - val expectedError = AuthErrorCode.MEMBER_NOT_FOUND runGetTest( mockMvc = mockMvc, endpoint = endpoint, @@ -132,13 +131,11 @@ class AuthControllerTest( val endpoint = "/logout" When("토큰으로 memberId 조회가 가능하면") { - every { - jwtHandler.getMemberIdFromToken(any()) - } returns 1L + loginAsUser() every { - memberFinder.findById(1L) - } returns MemberFixture.create(id = 1L) + authService.logout(user.id!!) + } just Runs Then("정상 응답한다.") { runPostTest( diff --git a/src/test/kotlin/roomescape/member/controller/MemberControllerTest.kt b/src/test/kotlin/roomescape/member/controller/MemberControllerTest.kt index d7a55fbc..5f3a9dc1 100644 --- a/src/test/kotlin/roomescape/member/controller/MemberControllerTest.kt +++ b/src/test/kotlin/roomescape/member/controller/MemberControllerTest.kt @@ -1,68 +1,53 @@ package roomescape.member.controller import com.ninjasquad.springmockk.MockkBean -import com.ninjasquad.springmockk.SpykBean import io.kotest.assertions.assertSoftly import io.kotest.matchers.collections.shouldContainAll import io.kotest.matchers.shouldBe import io.mockk.every -import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest import org.springframework.test.web.servlet.MockMvc import roomescape.auth.exception.AuthErrorCode import roomescape.member.business.MemberService import roomescape.member.exception.MemberErrorCode import roomescape.member.exception.MemberException -import roomescape.member.implement.MemberWriter import roomescape.member.infrastructure.persistence.Role -import roomescape.member.web.MemberController -import roomescape.member.web.MemberRetrieveListResponse -import roomescape.member.web.SignupRequest +import roomescape.member.web.* import roomescape.util.MemberFixture import roomescape.util.RoomescapeApiTest import kotlin.random.Random @WebMvcTest(controllers = [MemberController::class]) -class MemberControllerTest( - @Autowired private val mockMvc: MockMvc -) : RoomescapeApiTest() { - - @SpykBean - private lateinit var memberService: MemberService - +class MemberControllerTest(val mockMvc: MockMvc) : RoomescapeApiTest() { @MockkBean - private lateinit var memberWriter: MemberWriter - + private lateinit var memberService: MemberService init { given("GET /members 요청을") { val endpoint = "/members" - - every { memberFinder.findAll() } returns listOf( + val response = listOf( MemberFixture.create(id = Random.nextLong(), name = "name1"), MemberFixture.create(id = Random.nextLong(), name = "name2"), MemberFixture.create(id = Random.nextLong(), name = "name3"), - ) + ).toRetrieveListResponse() + + every { memberService.findMembers() } returns response `when`("관리자가 보내면") { loginAsAdmin() then("성공한다.") { - val result: String = runGetTest( + val result: MemberRetrieveListResponse = runGetTest( mockMvc = mockMvc, endpoint = endpoint, ) { status { isOk() } - }.andReturn().response.contentAsString + }.andReturn().readValue(MemberRetrieveListResponse::class.java) - val response: MemberRetrieveListResponse = readValue( - responseJson = result, - valueType = MemberRetrieveListResponse::class.java - ) - assertSoftly(response.members) { - it.size shouldBe 3 - it.map { m -> m.name } shouldContainAll listOf("name1", "name2", "name3") + assertSoftly(result.members) { + it.size shouldBe response.members.size + it.map { m -> m.name } shouldContainAll response.members.map { m -> m.name } } } } @@ -107,14 +92,14 @@ class MemberControllerTest( ) `when`("같은 이메일이 없으면") { every { - memberWriter.create(any(), any(), any(), any()) + memberService.createMember(request) } returns MemberFixture.create( id = 1, name = request.name, account = request.email, password = request.password, role = Role.MEMBER - ) + ).toSignupResponse() then("id과 이름을 담아 성공 응답") { runPostTest( @@ -130,13 +115,12 @@ class MemberControllerTest( } `when`("같은 이메일이 있으면") { + val expectedError = MemberErrorCode.DUPLICATE_EMAIL every { - memberWriter.create(request.name, request.email, request.password, Role.MEMBER) - } throws MemberException(MemberErrorCode.DUPLICATE_EMAIL) + memberService.createMember(request) + } throws MemberException(expectedError) then("에러 응답") { - val expectedError = MemberErrorCode.DUPLICATE_EMAIL - runPostTest( mockMvc = mockMvc, endpoint = endpoint, diff --git a/src/test/kotlin/roomescape/time/web/TimeControllerTest.kt b/src/test/kotlin/roomescape/time/web/TimeControllerTest.kt index 2d4c9ebf..42543d34 100644 --- a/src/test/kotlin/roomescape/time/web/TimeControllerTest.kt +++ b/src/test/kotlin/roomescape/time/web/TimeControllerTest.kt @@ -21,18 +21,15 @@ import java.time.LocalDate import java.time.LocalTime @WebMvcTest(TimeController::class) -class TimeControllerTest( - val mockMvc: MockMvc, -) : RoomescapeApiTest() { - +class TimeControllerTest(val mockMvc: MockMvc) : RoomescapeApiTest() { @MockkBean private lateinit var timeService: TimeService init { - Given("등록된 모든 시간을 조회할 때") { + Given("GET /times 요청을") { val endpoint = "/times" - When("관리자인 경우") { + When("관리자가 보내면") { beforeTest { loginAsAdmin() } @@ -59,7 +56,7 @@ class TimeControllerTest( } } - When("관리자가 아닌 경우") { + When("관리자가 보내지 않았다면") { loginAsUser() val expectedError = AuthErrorCode.ACCESS_DENIED @@ -79,10 +76,10 @@ class TimeControllerTest( } } - Given("시간을 추가할 때") { + Given("POST /times 요청을") { val endpoint = "/times" - When("관리자인 경우") { + When("관리자가 보낼 때") { beforeTest { loginAsAdmin() } @@ -143,7 +140,7 @@ class TimeControllerTest( } } - When("관리자가 아닌 경우") { + When("관리자가 보내지 않았다면") { loginAsUser() Then("예외 응답") { @@ -160,10 +157,10 @@ class TimeControllerTest( } } - Given("시간을 삭제할 때") { + Given("DELETE /times/{id} 요청을") { val endpoint = "/times/1" - When("관리자인 경우") { + When("관리자가 보낼 때") { beforeTest { loginAsAdmin() } @@ -222,7 +219,7 @@ class TimeControllerTest( } } - When("관리자가 아닌 경우") { + When("관리자가 보내지 않았다면") { loginAsUser() Then("예외 응답") { @@ -238,28 +235,21 @@ class TimeControllerTest( } } - Given("날짜, 테마가 주어졌을 때") { - beforeTest { - loginAsUser() - } + Given("GET /times/search?date={date}&themeId={themeId} 요청을 ") { val date: LocalDate = LocalDate.now() val themeId = 1L - When("테마를 찾을 수 있으면") { - Then("해당 날짜와 테마에 대한 예약 여부가 담긴 모든 시간을 응답") { + When("회원이 보낼 때") { + beforeTest { + loginAsUser() + } + + Then("정상 응답") { val response = TimeWithAvailabilityListResponse( listOf( - TimeWithAvailabilityResponse(id = 1L, startAt = LocalTime.now(), isAvailable = true), - TimeWithAvailabilityResponse( - id = 2L, - startAt = LocalTime.now().plusMinutes(30), - isAvailable = false - ), - TimeWithAvailabilityResponse( - id = 1L, - startAt = LocalTime.now().plusHours(1), - isAvailable = true - ), + TimeWithAvailabilityResponse(1L, LocalTime.of(10, 0), true), + TimeWithAvailabilityResponse(2L, LocalTime.of(10, 1), false), + TimeWithAvailabilityResponse(3L, LocalTime.of(10, 2), true) ) ) every { @@ -285,15 +275,12 @@ class TimeControllerTest( this[1].isAvailable shouldBe response.times[1].isAvailable } } - } + Then("테마를 찾을 수 없으면 예외 응답") { + val expectedError = ThemeErrorCode.THEME_NOT_FOUND + every { + timeService.findTimesWithAvailability(date, themeId) + } throws ThemeException(expectedError) - When("테마를 찾을 수 없으면") { - val expectedError = ThemeErrorCode.THEME_NOT_FOUND - every { - timeService.findTimesWithAvailability(date, themeId) - } throws ThemeException(expectedError) - - Then("예외 응답") { runGetTest( mockMvc = mockMvc, endpoint = "/times/search?date=$date&themeId=$themeId", @@ -303,6 +290,23 @@ class TimeControllerTest( } } } + + When("비회원이 보내면") { + doNotLogin() + + Then("예외 응답") { + val expectedError = AuthErrorCode.MEMBER_NOT_FOUND + + runGetTest( + mockMvc = mockMvc, + endpoint = "/times/search?date=$date&themeId=$themeId", + ) { + status { isEqualTo(expectedError.httpStatus.value()) } + jsonPath("$.code", equalTo(expectedError.errorCode)) + } + + } + } } } }