Junit5 사용법 정리

devdo·2021년 8월 2일
0

TDD

목록 보기
2/6

Junit이란?

Java 기반의 Java를 위한 단위 테스트를 위한 프레임워크이다.
Annotation 기반으로 테스트를 지원하며, Assert를 통해서 (예상, 실제 )를 통해 검증한다.

참고로, Spring Boot는 버전 2.2부터 JUnit5를 기본적으로 사용할 수 있도록 설정되었다.

Junit을 알아보기 전에 먼저 개념을 정리해봅시다.

TDD(Test-driven Development)
테스트 주도 개발에서 사용하지만, 코드의 유지보수 및 운영환경에서의 에러를 미리 방지하기 위해서 단위 별로 검증 하는 테스트 프레임워크
https://velog.io/@mooh2jj/TDD란

단위테스트
작성한 코드가 기대하는 대로 동작을 하는지 가장 작은 소프트웨어를 실행하여 검증하는 테스트.

통합테스트
단위 테스트보다 더 큰 동작을 달성하기 위해 여러 모듈들을 모아 이들이 의도대로 협력하는지 확인하는 테스트.

기능테스트(E2E 테스트)
사용자 입장에서 시스템이 제공하는 기능이 올바르게 동작하는지 확인하는 테스트, 즉, 사용자가 직접 사용하는 웹 브라우저나 모바일 앱부터 시작해서 DB, 외부 서비스에 이르기까지 모든 구성 요소를 하나로 엮어서 진행한다. QA팀이 하는 테스트가 보통 기능테스트이다.

단위테스트 vs 통합테스트

통합 테스트는 단위 테스트와 달리 개발자가 변경할 수 없는 부분(ex. 외부 라이브러리)까지 묶어 검증할 때 사용한다. 이는 DB에 접근하거나 전체 코드와 다양한 환경이 제대로 작동하는지 확인하는데 필요한 모든 작업을 수행할 수 있다. 그러나, 통합 테스트가 응용 프로그램이 완전하게 작동하는 걸 무조건 증명하지는 않는다.

통합 테스트의 장점은 단위 테스트에서 발견하기 어려운 버그를 찾을 수 있다는 점이다. 예를 들어, 통합 테스트에서는 환경 버그(ex. 싱글 코어 CPU에서는 잘 실행되나 쿼드 코어 CPU에서는 잘 실행되지 않음)이 발생할 수 있다.

한편, 통합 테스트의 단점은 단위 테스트보다 더 많은 코드를 테스트하기 때문에 신뢰성이 떨어질 수 있다는 점이다. 또, 어디서 에러가 발생했는지 확인하기 쉽지 않아 유지보수하기 힘들다는 점도 있다.

통합 테스트에서는 클래스 상단에 @SpringBootTest 어노테이션을 붙여 를 수행할 수 있다.

  • 단위테스트 : H2 메모리
  • 통합테스트 : 실제 사용 DB

✅참고: 스프링 부트에 아무런 설정도 하지 않으면 h2 DB(embeded DB)를 메모리 모드로 JVM안에서 실행한다.


Mock vs Stub

  • Mock : 유닛 테스트 등을 작성할 때 해당 코드가 의존성을 가지고 있다면 그 의존하는 부분을 가짜로 대체한 객체
    @Mock
    private StudyGroupRepository studyGroupRepository;

    @InjectMocks
    private StudyGroupService studyGroupService;
  • stub : 아직 준비되지 못한 코드를 미리 기대한 답변으로 반환할 수 있도록 하는 메커니즘.
	// stubbing , Mocikto.when()
	when(mockedList.get(0)).thenReturn("ok");
	when(mockedList.get(1)).thenThrow(new RuntimeException());
    
    // stubbing, BDDMockito.given() => 주로 애를 많이 사용함.
    given(mockedList.get(0)).willReturn("ok");

둘 모두의 목적은

가짜 객체가 실제로 동작하는 것처럼 보이게 만들어놓은 객체를 활용하여, 호출자를 실제 구현물로부터 격리시켜 독립적인 테스트를 진행할 수 있도록 하는 것이다.

출처: https://hyeonyeee.tistory.com/98 [hyeoneee's blog]

구현 방법

먼저 라이브러리를 추가해야 합니다.

Junit4

// gradle
testImplementation 'junit:junit:4.12'

Junit5
자바 8이상부터 사용가능, JUnit Platform과 Junit jupiter, Junit Vintage 결합한 형태.

Spring Boot는 버전 2.2부터 JUnit5를 기본적으로 사용할 수 있도록 설정되었다.

기본적으로 이 디팬더시로 JUnit5 의존성 라이브러리들이 전부 가져다 준다.

// gradle
testImplementation 'org.springframework.boot:spring-boot-starter-test'

Junit5 특징


Junit5 메서드 정리

https://steady-coding.tistory.com/349


기본 예제

그리고 Test용 클래스를 만들어줍니다.
이 클래스는 인텔리제이라면

ctrl + shift + T

를 눌러주면 자동 생성됩니다.

build.gradle

testImplementation 'org.springframework.boot:spring-boot-starter-test'

// test에서 lombok 사용 -> @Sl4j 사용가능
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
// test sql 확인용
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.8.0'

test dumy 데이터 생성 및 List 확인

import org.junit.jupiter.api.Test;	// 꼭 @Test는 jupiter.api.Test로 받아야!

@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) // 이걸 같이 붙여줘야 @Order 적용이 됨!
@SpringBootTest // 통합테스트
@Transactional // rollback
@ActiveProfiles("test")  // application-test.yml 설정을 받음
class MemoTest {

    @Autowired
    private MemoRepository memoRepository;
    
    @Order(1)
    @Test
    @DisplayName("saveTest")
    public void save() {
        LongStream.rangeClosed(1,30).forEach( i -> {
            Memo memo = Memo.builder()
                    .title("title_"+i)
                    .content("content_"+i)
                    .build();
            memoRepository.save(memo);
        });
        
    }

	@Order(2)
	@Test
    @DisplayName("getAll 테스트")
    public void getAll() {

        List<Memo> all = memoRepository.findAll();
        log.info("all : {}", all);

        System.out.println("all = " + all);
        assertThat(all.size()).isGreaterThan(30);  // Assertions -> assertj.core 패키지 import
    }

}

클래스 Calculator, 그리고 그 안에 메서드 sum()를 만들어줍시다.

package com.example.mocktest.model;

public class Calculator {
    public int sum(int num1, int num2) {
        return num1 + num2;
    }
}
package com.example.mocktest.model;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class CalculatorTest {

    @Test
    void sum() {
        Calculator calculator = new Calculator();
        int result = calculator.sum(10, 20);
        assertEquals(30, result);
    }
}

여기서 assertEquals(expected, actual)는 두 값이 같은지 여부를 판단하는 Junit jupiter 단언(assert) 메서드이다.

x=y가 맞다면 결과는 이렇게 나온다.


Assertj 라이브러리

Assertions 라이브러리로 두 가지를 들 수 있다.
1) Jupiter
2) Assertj

가독성이 좋고 쉽게 사용하기에는 여러 개발자분들은(대표적 백기선, 김영한 등) AssertJ를 많이 추천해준다.

assertThat(dto.getName()).isEqualTo(name);


참고

https://tecoble.techcourse.co.kr/post/2021-05-25-unit-test-vs-integration-test-vs-acceptance-test/

profile
배운 것을 기록합니다.

0개의 댓글