junit으로 시작하는 TDD

문지은·2021년 9월 13일
0

TDD

목록 보기
1/2

🌈 TDD는 무엇일까?

Test Driven Development, 즉 테스트 코드를 먼저 짜놓고 해당 테스트를 통과하는 코드를 구현하는 것!

Red, Green, Blue 과정을 통해서 코드를 구현한다.

  • Red : 먼저 테스트 코드를 작성하면 당연히 작성된 코드가 없으니 오류가 뜬다.
  • Green : 테스트 코드에서 빨간 줄을 없애도록 코드를 구현한다.
  • Blue : 리팩토링하는 과정! 테스트를 성공하는 코드 내에서 리팩토링을 통해서 더 효율적이고 가독성 좋은 코드로 바꾼다.

테스트를 할 때 주의할 점이 있다. 모든 기능에 대해서 다 세세하게 테스트를 작성하지 말 것!

왜냐하면 테스트 코드와 구현 코드 사이의 dependency가 너무 높아져서 요구 사항이 바뀌면 계속 바꿔줘야 하기 때문이다.

대표적인 tool로는 junit이 있다.

🌈 junit 에 대해서 알아보자

아래가 junit의 기본 툴이라고 볼 수 있다.

    @Test
    @DisplayName("테스트를 진행해보자")
    void simpleTest()
    {
        // given
        // 이런 조건에서
        
        // when
        // 이런 동작을 진행하면
        
        // then
        // 이런 결과가 발생한다.

    }
  • @BeforeAll, @BeforeEach : 테스트 실행되기 전에 실행할 set up 코드 작성.

BeforeAll은 전체 실행되기 전에 한번. BeforeEach 는 매 실행 전에 한번.

이제 나온 결과가 우리가 예상한 결과와 일치하는지 알아보자.

이 때 필요한 것이 바로 Assertion!

@Test
void AssumptionTest()
{
	
    //boolean test
    assumeTrue(true);
    assumeFalse(false);
    
    //equal test
    assertEquals(myResult, actualResult);
    
    //exception test
    Throwable exception = assertThrows(NullPointerException.class, () -> {
    	throw new NullPointerException("null pointer exception이 발생했습니다.");
    })
    assertEquals(exception.getMessage(), "null pointer exception이 발생했습니다.");
    
}

🌈 더 구체적인 사용 예시를 참고하기 위해서 내가 하고 있는 토이 플젝에서의 junit test 예시를 첨부한다~!

내 토이 프로젝트는 spring boot와 mybatis를 사용했다!

그래서 그 둘 사이의 연동이 잘 이루어졌는지 확인하기 위해서 테스트 코드를 작성했다.

첫번째 테스트에서는 builder를 통해서 requestDto를 만들고 insert함으로써 해당 아이디가 잘 생성됐는지 확인하는 과정

두번째 테스트는 DataAccessException을 잘 발생시키고 있는지 확인하는 과정

class UserMapperTest extends IntegrationTest
{
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Test
    @DisplayName("Mybatis 연동 확인, Insert 쿼리 작동 확인")
    void addMember()
    {
        // given
        UserSignUpApiRequest request = UserSignUpApiRequest.builder()
            .userId("user")
            .businessName(null)
            .userName("nick")
            .password("password")
            .userType("ordinary")
            .userAddress("address")
            .userPhone("010-0101-0101")
            .build();
        User user = request.toUser(passwordEncoder);

        // when
        userMapper.addUser(user);

        // then
        assertNotNull(user.getUserId());
    }
    
    

    @Test
    @DisplayName("Mybatis가 sql 쿼리 오류를 DataAccessException으로 던져주는 것 확인")
    void addMember_X()
    {
        // given
        UserSignUpApiRequest request = UserSignUpApiRequest.builder()
            .userId("user")
            .businessName(null)
            .userName("nick")
            .password("password")
            .userType("ordinary")
            .userAddress("address")
            .userPhone("010-0101-010192138572398572319857239857128") // 컬럼 길이 제한 제약 조건 위배
            .build();
        User user = request.toUser(passwordEncoder);

        // when
        // then
        assertThrows(DataAccessException.class, () -> userMapper.addUser(user));
    }
}

그런데 위와 같은 상황에서 우리는 user 회원 가입 과정만 테스트하고 싶지 그것이 테이블에 제대로 들어갔는지는 테스트하고 싶지 않을 수가 있다. 우리의 관심사가 mapper가 아닌 service나 다른 쪽에 있을 수도 있다는 얘기! 하지만 테스트를 하려면 mapper를 거칠 수 밖에 없다..

이럴 때 필요한 게 바로 mock이다!

mock에 대해서 다음 포스트에 이어서 작성해보도록 하겠다✌️

profile
백엔드 개발자입니다.

0개의 댓글