JUnit Test란?


1. 배경지식

1) 테스트 구현이 필요한 이유

버그를 잡기위한 효과적인 수단은 테스트와 로그 메시지다.
사람이 직접 테스트를 실행하는 것은 대부분 너무 많은 시간이 필요하다.

아까까지 잘 돌아갔던 기능인데, 소스코드를 수정한 후 갑자기 에러가 발생하는 경우가 많다.
그래서 소스코드를 수정할 때 마다, 모든 기능들을 전부 다시 테스트 해야 안전한다.
사람의 수작업 없이 자동 테스트 할 수 있도록 테스트를 구현하는 것이 필수다.

출력된 값을 눈으로 확인해 보는 것도 시간이 걸린다.
결과 같이 정상인지 아닌지 확인해 보는 기능까지 테스트 코드에 구현해야 한다.
그래서 테스트 결과 정상인지 아닌지만 보고되어야 한다.

JUnit 테스트를 열심히 구현하지 않는 프로그래머는 버그 때문에 고생할 확률이 높다.




2) 단위 테스트

클래스를 하나씩 따로 테스트 하는 것이 단위 테스트(Unit Test)이다.
프로젝트 전체를 실행하면서 테스트하면 에러가 발생했을 경우에 문제의 원인이 어디에 있는지 알기 어려운 경우가 종종 있다.
클래스 하나 메소드 하나씩 따로 테스트하면, 에러를 찾고 수정하기 쉽다.




3) 통합 테스트

단위 테스트를 통과한 클래스들의 객체를 서로 연결하여 같이 테스트 하는 것이 통합 테스트이다.
예를들어, StudentMapper 클래스를 따로 단위 테스트하고 StudentService 클래스를 따로 단위 테스트하고,
이들 객체를 연결(@Autowired)하여 같이 테스트하는 것이 통합 테스트이다.




4) 테스트 Mock

StudentService 클래스는 StudentMapper 클래스의 메소드를 호출한다.
따라서 StudentService 클래스의 단위 테스트를 하려면 StudentMapper 클래스가 있어야 한다.
그런데 StudentService 객체와 StudentMapper 객체를 연결하여 같이 테스트하는 것은 통합 테스트이지 단위 테스트가 아니다.
StudentService 클래스를 단위 테스트할 때는 테스트용 가짜 StudentMapper 클래스를 만들어서 StudentService 객체에 연결하여 테스트 해야 한다.
이렇게 테스트용으로 만드는 가짜 클래스를 테스트 Mock 클래스라고 부른다.
Spring boot 앱에는 Mockito 프레임워크 라이브러리가 포함되어 있다.
Mockito를 이용해서 Mock을 구현해야 한다.




5) JUnit 라이브러리

Java 언어로 단위 테스트를 규현하기 위한 표준 라이브러리가 JUint이다.




6) import static

import java.util.Arrays;         

. . .

int[] a = new int[]{2, 3, 1, 6, 5, 7};
Arrays.sort(a);        

Arrays 클래스가 import 되었기 때문에 Arrays.sort 메소드를 호출할 수 있다.


import static java.util.Arrays.sort;

. . .       

int[] a = new int[]{2, 3, 1, 6, 5, 7};
sort(a);

Arrays 클래스의 sort 메소드가 import 되었기 때문에 Arrays 클래스를 생략하고
바로 sort 메소드를 호출해도 된다.


import static org.junit.Assert;

. . .          

Assert.assertEquals(s1, s2);
Assert.assertNotNull(s1);
Assert.assertNull(s2);
Assert.assertTrue(s1.equals(s2));


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

. . .          

assertEquals(s1, s2);
assertNotNull(s1);
assertNull(s2);
assertTrue(s1.equals(s2));

Assert. 을 생략할 수 있다.



2. test1 프로젝트

전체 코드 보러가기


Student.java

import lombok.Data;

. . .

@Data

Lombok에 의해서 get/set 메소드 뿐만 아니라, equals 메소드와 hashcode 메소드도 자동으로 재정의된다.


StudentMapperTests.java

assertEquals(student1, student2);
student1, student2 값을 화면에 출력하고, 그 값이 동일한지 눈으로 확인하는 것은 바람직하지 않다.
값이 동일한지 확인하는 코드를 구현하는 것이 바람직하다.
Assert 클래스의 assertEquals 메소드는 두 객체의 값이 동일한지 검사하는 메소드이다.
동일하면 테스트 통과이고, 동일하지 않으면 테스트 실패이다.


@Transactional
테스트 클래스에 @Transactional을 붙여주면,
@Test 어노테이션이 붙은 테스트 메소드에서 실행한 DB insert/update/delete 작업은,
그 메소드가 리턴될 때 모두 자동으로 취소(rollback) 된다.