[JUnit5] @BeforeEach 활용

Tae Woo Kim·2024년 7월 22일

Java

목록 보기
3/6

문제

Repository Layer 유닛테스트 중 각 테스트마다 given절에 User가 필요하다.
여러 메소드에 계속

		User user = User.builder()
                .email("test@example.com")
                .password("password")
                .role(Role.USER)
                .build();
        user = userRepository.save(user)

이걸 써주면 좋겠지만, 그러기엔 너무 반복된다.

해결

필드 선언

testUser를 class field로 선언해준다. 해당 클래스 내에 다른 테스트 메소드들이 접근할 수 있도록.

@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class EntryRepositoryTest {

    @Autowired
    private EntryRepository entryRepository;
    
    // ...생략

    // declare testUser as class field for use
    private User testUser;
    
    // ... 생략

@BeforeEach 활용

@BeforeEach를 사용하여 각 테스트 시작 전 testUser를 만들어준다.

    @BeforeEach
    void setUp() {
        testUser = User.builder()
                .email("test@example.com")
                .password("password")
                .role(Role.USER)
                .build();
        testUser = userRepository.save(testUser);
    }

BeforeEach는 말그대로 각각의 테스트가 시작하기 전 한 번씩 실행된다.

코드

package com.written.app.repository;

import com.written.app.model.Entry;
import com.written.app.model.Label;
import com.written.app.model.Role;
import com.written.app.model.User;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class EntryRepositoryTest {

    @Autowired
    private EntryRepository entryRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private LabelRepository labelRepository;

    // declare testUser as class field for use
    private User testUser;

    @BeforeEach
    void setUp() {
        testUser = User.builder()
                .email("test@example.com")
                .password("password")
                .role(Role.USER)
                .build();
        testUser = userRepository.save(testUser);
    }

    @Test
    public void EntryRepository_Save_ReturnEntry() {
        // given
        Label label = Label.builder()
                .name("Test Label")
                .user(testUser)
                .build();
        label = labelRepository.save(label);


        Entry entry = Entry.builder()
                .title("Title01")
                .content("Content\n01")
                .label(label) // fk
                .user(testUser) // fk
                .build();

        // when
        Entry savedEntry = entryRepository.save(entry);

        // then
        Assertions.assertThat(savedEntry).isNotNull();
        Assertions.assertThat(savedEntry.getId()).isGreaterThan(0);
        Assertions.assertThat(savedEntry.getUser()).isEqualTo(testUser);
        Assertions.assertThat(savedEntry.getLabel()).isEqualTo(label);
    }

    @Test
    public void EntryRepository_SaveWithoutLabel_ReturnEntry() {
        // given
        Entry entry = Entry.builder()
                .title("Title01")
                .content("Content01")
                .user(testUser)
                .build();

        // when
        Entry savedEntry = entryRepository.save(entry);

        // then
        Assertions.assertThat(savedEntry).isNotNull();
        Assertions.assertThat(savedEntry.getId()).isGreaterThan(0);
        Assertions.assertThat(savedEntry.getUser()).isEqualTo(testUser);
        Assertions.assertThat(savedEntry.getLabel()).isNull();
    }
}

결론

@BeforeEach를 잘 활용하면 여러번 쓸 것을 한 번 쓰고 행복한 코딩을 할 수 있다!

주의점

email unique constraint을 줬는데 저장된 testUser들이 똑같은 email을 가지고 있다.

setUp 메소드:

    @BeforeEach
    void setUp() {
        testUser = User.builder()
                .email("test@example.com")
                .password("password")
                .role(Role.USER)
                .build();
        testUser = userRepository.save(testUser);
        System.out.println("testUser = " + testUser); // 여기서 유저 로깅
    }

로그:

testUser = User(id=1, email=test@example.com, password=password, nick=null, isDeleted=false, createdAt=null, role=USER, tokens=null, entries=null, lists=null, labels=null)
testUser = User(id=2, email=test@example.com, password=password, nick=null, isDeleted=false, createdAt=null, role=USER, tokens=null, entries=null, lists=null, labels=null)
testUser = User(id=3, email=test@example.com, password=password, nick=null, isDeleted=false, createdAt=null, role=USER, tokens=null, entries=null, lists=null, labels=null)

왜 예외가 발생안하지?

  • 다음편에 계속...

다음편: [JPA] 영속성 컨텍스트 맛보기

0개의 댓글