package roomescape.member.business import io.kotest.assertions.assertSoftly import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk import roomescape.member.exception.MemberErrorCode import roomescape.member.exception.MemberException import roomescape.member.implement.MemberFinder import roomescape.member.implement.MemberWriter import roomescape.member.infrastructure.persistence.MemberEntity import roomescape.member.infrastructure.persistence.Role import roomescape.member.web.SignupRequest import roomescape.util.MemberFixture class MemberServiceTest : FunSpec({ val memberWriter: MemberWriter = mockk() val memberFinder: MemberFinder = mockk() val memberService = MemberService(memberWriter, memberFinder) context("findMembers") { test("정상 응답") { val members: List = listOf( MemberFixture.create(name = "user1"), MemberFixture.create(name = "user2"), ) every { memberFinder.findAll() } returns members val response = memberService.findMembers() // then assertSoftly(response.members) { it shouldHaveSize 2 it.map { member -> member.name } shouldContainExactly listOf("user1", "user2") } } } context("findById") { val id = 1L test("정상 응답") { every { memberFinder.findById(id) } returns MemberFixture.create(id = id) memberService.findById(id).id shouldBe id } test("회원을 찾을 수 없으면 예외 응답") { every { memberFinder.findById(id) } throws MemberException(MemberErrorCode.MEMBER_NOT_FOUND) shouldThrow { memberService.findById(id) }.also { it.errorCode shouldBe MemberErrorCode.MEMBER_NOT_FOUND } } } context("createMember") { val request = SignupRequest(name = "new-user", email = "new@test.com", password = "password") test("정상 저장") { val member = MemberFixture.create( name = request.name, account = request.email, password = request.password ) every { memberWriter.create(request.name, request.email, request.password, Role.MEMBER) } returns member val response = memberService.createMember(request) response.id shouldBe member.id } test("중복된 이메일이 있으면 예외 응답") { every { memberWriter.create(request.name, request.email, request.password, Role.MEMBER) } throws MemberException(MemberErrorCode.DUPLICATE_EMAIL) shouldThrow { memberService.createMember(request) }.also { it.errorCode shouldBe MemberErrorCode.DUPLICATE_EMAIL } } } })