인프런 커뮤니티 질문&답변

relate16님의 프로필 이미지
relate16

작성한 질문수

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

스프링통합테스트시.. IllegalStateException

해결된 질문

작성

·

393

0

h2 데이터에는 delete from member 로 데이터 다 삭제한 상태인데

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest
@Transactional
class MemberServiceIntegrationTest {
//@SpringBootTest 스프링 컨테이너와 테스트를 연결해줌.
//@Transactional test 함수 하나를 실행 후 commit까지 하지 않고 rollback을 시켜준다. 따라서 store.clear()같은 게 필요 없다.
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
/*@BeforeEach
void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
는 순수 java의 테스트여서 Spring 통합테스트에서는 @BeforeEach를 사용하지 않고
@Autowired를 통해 객체를 끌어다 쓴다. , 생성자를 만들어도 되지만
테스트는 객체를 다른데서 이어서 쓸 게 아니기 때문에 편하게 @Autowired만으로 써도 된다.
참고. 현재 MemberRepository new JdbcMemberRepository(dataSource); 로 등록되어 있다.
}*/

@Test
void join() {
Member member = new Member();
member.setName("hi2");
Long savedId = memberService.join(member);
Member savedMember = memberRepository.findById(savedId).get();
Assertions.assertThat(savedMember.getName()).isEqualTo(member.getName());
}

@Test
void validDuplicateMember() {
Member member1 = new Member();
member1.setName("hi123");
Member member2 = new Member();
member2.setName("hi123");

memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> { memberService.join(member2); });
Assertions.assertThat(e.getMessage()).isEqualTo("이미존재하는 회원입니다");

}

를 실행하면 모든 함수에서 이미존재하는 회원이라고 뜹니다(다른 Test코드 포함)

2021-05-29 11:42:58.502  INFO 14008 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...

2021-05-29 11:42:58.785  INFO 14008 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.

2021-05-29 11:42:58.806  INFO 14008 --- [           main] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@45815ffc testClass \ 생략..

2021-05-29 11:42:59.813  INFO 14008 --- [           main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test: [DefaultTestContext@45815ffc testClass = 생략.. ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]

java.lang.IllegalStateException: 이미존재하는회원입니다

at hello.hellospring.service.MemberService.lambda$validDuplicateMember$0(MemberService.java:24)

at java.base/java.util.Optional.ifPresent(Optional.java:183)

at hello.hellospring.service.MemberService.validDuplicateMember(MemberService.java:23)

at hello.hellospring.service.MemberService.join(MemberService.java:17)

at hello.hellospring.service.MemberServiceIntegrationTest.validDuplicateMember(MemberServiceIntegrationTest.java:48)

<..생략..>

at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

이라고 나옵니다.

순수JDBC 테스트코드에선 정상작동하는데 

이것저것해보다가 안돼서 질문남깁니다..  죄송합니다 :( 

JDBC순수 test코드:

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


class MemberServiceTest {

MemberService memberService;
MemoryMemberRepository memberRepository;
@BeforeEach
void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}

@AfterEach
void afterEach() {
memberRepository.clearStore();
}

@Test
void join() {
Member member = new Member();
member.setName("hi");
Long savedId = memberService.join(member);
Member savedMember = memberRepository.findById(savedId).get();
Assertions.assertThat(savedMember.getName()).isEqualTo(member.getName());
}

@Test
void validDuplicateMember() {
Member member1 = new Member();
member1.setName("hi");
Member member2 = new Member();
member2.setName("hi");

memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> { memberService.join(member2); });
Assertions.assertThat(e.getMessage()).isEqualTo("이미존재하는회원입니다");

}

MemberService 코드 :

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import java.util.List;
import java.util.Optional;

public class MemberService {
MemberRepository memberRepository;

public MemberService(MemberRepository memberRepository) {

this.memberRepository = memberRepository;
}

public Long join(Member member) {
validDuplicateMember(member);//name중복확인
memberRepository.save(member);
return member.getId();
}

private void validDuplicateMember(Member member) {
memberRepository.findByName(member.getName()).ifPresent(m -> {
throw new IllegalStateException("이미존재하는회원입니다");
});
}

답변 2

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. relate16님

확인해보니 JdbcMemberRespository.findByName()의 로직이 잘못 작성되어 있습니다.

member 객체 조건과 무관하게 항상 반환하도록 개발되어 있습니다.

메뉴얼을 참고해서 해당 로직을 다시 작성해주세요.

감사합니다.

relate16님의 프로필 이미지
relate16
질문자

해결하고 의문점이 생겼어서 답글로 한 번 더 물어봤는데(현재는 삭제한 상태입니다),

고민하고 쭉 타고 올라가길 반복하면서

다 해결했습니다 !! 정말정말 감사합니다 ! :]

김영한님의 프로필 이미지
김영한
지식공유자

화이팅^^!

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. relate16님

전체 프로젝트를 압축해서 올려주세요.

감사합니다.

 

relate16님의 프로필 이미지
relate16
질문자

감사합니다. 첨부해서 보냈습니다 :]

relate16님의 프로필 이미지
relate16

작성한 질문수

질문하기