2장 테스트
JUnit이란
자바 프로그래밍 언어용 유닛 테스트 프레임워크
JUnit 5 구조
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
JUnit Platfom : JVM에서 테스트 프레임워크를 시작하기 위한 기반 역할
JUnit Jupiter : 테스트들을 작성하기 위한 새로운 프로그래밍과 확장 모델의 조합
JUnit Vintage : JUnit 5 플랫폼 상에서 JUnit 3과 JUnit 4 기반의 테스트들이 구동되는 것을 지원
JUnit 동작 방식
1. 테스트 클래스에서 @Test가 붙은 public이고 void형이며 파라미터가 없는 테스트 메서드를 모두 찾는다.
2. 테스트 클래스의 오브젝트를 하나 만든다
com.example.demo.UserDaoTest@1fc2b765
getUserFailure
com.example.demo.UserDaoTest@a3d8174
andGet
com.example.demo.UserDaoTest@2accdbb5
count
3. @BeforeAll 붙은 메서드가 있으면 실행한다.
4. @BeforeEach가 붙은 메서드가 있으면 실행한다.
5. @Test가 붙은 메소드를 하나 호출하고 테스트 결과를 저장해둔다.
6. @AfterEach가 붙은 메서드가 있으면 실행한다.
7. 나머지 테스트 메서드에 대해 4~6번을 반복한다
8. @AfterAll가 붙은 메서드가 있으면 실행한다.
7. 모든 테스트의 결과를 종합해서 돌려준다.
픽스처
테스트를 수행하는 데 필요한 정보나 오브젝트
여러 테스트에서 반복적으로 사용되기 때문에 @BeforeEach 메소드를 이용해 생성
@BeforeEach
public void setUp() {
this.user1 = new User("gyumee", "박성철", "springno1");
this.user2 = new User("leegw700", "이길원", "springno2");
this.user3 = new User("bumjin","박범진","springno3");
dao = new UserDao();
DataSource dataSource = new SingleConnectionDataSource("jdbc:mysql://localhost/testdb", "spring", "book", true);
dao.setDataSource(dataSource);
}
Junit 4 : @Before -> Junit 5 : @BeforeEach
각각의 테서트 메서드 전에 실행
Junit 4 : @After -> Junit 5 : @AfterEach
각각의 테스트 메서드 후에 실행
Junit 4 : @BeforeClass -> Junit 5 : @BeforeAll
현재 클래스에서 모든 테스트 메서드들 전에 실행
Junit 4 : @AfterClass -> Junit 5 : @AfterAll
현재 클래스에서 모든 테스트 메서드들 후에 실행
BeforeAll, AfterAll은 메서드가 static 메소드여야 컴파일이 됨
Junit 4 : @ignore -> Junit 5 : @Disable
테스트 클래스 나 메서드를 비활성화
package com.example.demo;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
public class JUnitAnnotationTest {
@BeforeEach
public void beforeEach() {
System.out.println("BeforeEach");
}
@AfterEach
public void afterEach() {
System.out.println("AfterEach");
}
@BeforeAll
static public void beforeAll() {
System.out.println("beforeAll");
}
@AfterAll
static public void afterAll() {
System.out.println("afterAll");
}
@Disabled
public void disabled() {
System.out.println("disabled");
}
@Test
public void test1() {
System.out.println("test1");
}
@Test
public void test2() {
System.out.println("test2");
}
}
결과
beforeAll
beforeEach
test1
afterEach
beforeEach
test2
afterEach
afterAll
Junit 4 : @RunWith -> Junit 5 : @ExtendWith
JUnit 프레임워크의 테스트 실행방법을 확장할 때 사용하는 어노테이션
@ContextConfiguration란?
테스트를 위해 Application Context를 로드하고 구성하는 방법을 결정함
class level에서 정의함
@ContextConfiguration("/applicationContext.xml")
public class UserDaoTest {
@Autowired란?
인스턴스 변수에 붙어있을 경우 변수 타입과 일치하는 컨텍스트 내의 빈을 찾음
@Autowired
private UserDao dao;
ApplicationContext는 ApplicationContext.xml에 빈 정의를 안해줬는데 DI가 된 이유는?
-> 스프링 애플리케이션 컨텍스트는 초기화할때 자기 자신도 빈으로 등록하기 때문
단점
같은 타입의 빈이 두 개 이상 있는 경우에는 타입만으로는 어떤 빈을 가져올지 결정할 수 없다.
@DirtiesContext
테스트 메소드에서 애플리케이션 컨텍스트의 구성이나 상태를 변경한다는 것을
테스트 컨텍스트 프레임워크에 알려준다.
테스트 컨텍스트는 이 어노테이션이 붙은 테스트 클래스에는 애플리케이션 컨텍스트 공유를 허용하지 않고
테스트 메소드를 수행하고 나면 매번 새로운 애플리케이션 컨텍스트를 만듬
SingleConnectionDataSource.class
DB 커넥션을 하나만 만들어두고 계속 사용하기 때문에 매우 빠르다.