단위테스트는 전체 어플리케이션을 구동하지않고 일부분만 실행하여 테스트하는 것이 목적이다. 가령 스프링을 사용중이고 서비스 빈을 테스트 한다고할 때, 레포지토리는 컨텍스트에서 인젝션 받을 수 없기때문에 직접 생성자로 생성하여 사용한다. 이때 @Before 애너테이션으로 테스트용 객체를 초기화 할 수도 있지만 목(Mock)을 사용하는 방법이 있다.
서비스를 인터페이스로 만들고, 구현체를 작성할 경우도 있다. 이 경우에는?
@ParameterizedTest ?단위 테스트는 test디렉터리에 동일한 경로를 미러링하고 클래스이름마지막에 Test를 붙이는 것이 관례. Junit 의 Assertions나 Asserj 사용.
import static org.assertj.core.api.AssertionsForClassTypes.*assertThat*;💡아래 키워드를 주석으로 사용할 것을 권장
<aside>
@Test
void join() {
//given
Member member = new Member();
member.setName("john");
//when
memberService.join(member);
//then
Member result = memberService.findOne(member.getId()).get();
assertThat(result).isEqualTo(member);
}
</aside>
Junit 주요 메서드
@Test : 테스트 메서드임을 선언
@BeforeEach(= Junit4의 Before) : 각각의 테스트 메서드가 실행되기 전에 실행되는 메서드
@AfterEach : 각각의 테스트 메서드가 실행된 후에 실행되는 메서드
@BeforeAll : 테스트 클래스가 실행되기 전에 한번만 실행 (static 메서드여야 함)
//DI 적용된 구문
private final MemberRepository memoryRepository;
public MemberService(MemberRepository memoryRepository) {
this.memoryRepository = memoryRepository;
}
//-------------------------------------------------
MemberService memberService;
MemoryMemberRepository memberRepository;
@BeforeEach
public void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
@AfterEach
public void afterEach(){
memberRepository.clearStore(); // 이걸 사용하기 위해서
}
@AfterAll : 테스트 클래스의 모든 테스트가 끝난 후 한번만 실행 (static 메서드여야 함)
@DisplayName : 테스트 클래스나 메서드의 이름을 지정
assertThrows() : 예외 발생을 검증
throw new IllegalStateException("이미 존재하는 회원입니다.");
//-------------------------------------------
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
assertTimeout() : 실행 시간 제한을 검증
assertAll() : 여러 검증을 그룹화하여 모든 실패 케이스를 한번에 확인
fail() : 테스트가 강제로 실패하도록 설정하는 메서드.
Assertj
모킹의 목적 : 테스트를 더 쉽게, 독립적으로, 그리고 안정적으로 수행하기 위한 것입니다. 이를 통해 코드의 특정 부분만 집중적으로 테스트하고, 외부 종속성이나 환경과 관련된 문제를 배제할 수 있습니다
@ExtendWith(MockitoExtension.class) : 해당 테스트클래스를 ****JUnit 5 (@Test)에서 Mockito를 사용할 수 있게 해주는 확장 기능
@Mock : 가짜 객체(Mock)로 지정한다. (@MockBean은 통합테스트용)
@Mock
private UserRepository userRepository;
@InjectMocks : Mockito가 생정자나 필드의 @Mock으로 만들어진 객체에 자동으로 주입
@InjectMocks
private UserService userService;