✅ UserDaoTest 다시보기
이전에 만들었던 테스트 코드는 main() 메소드를 이용해 UserDao 객체의 add(), get() 메소드를 호출하고, 그 결과를 화면에 출력하여 테스트하였다.
- UserDaoTest
package com.jhcode.spring.ch1.dao; import java.sql.SQLException; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import com.jhcode.spring.ch1.domain.User; public class UserDaoTest { public static void main(String[] args) throws ClassNotFoundException, SQLException { ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); UserDao dao = context.getBean("userDao", UserDao.class); User user = new User(); user.setId("dataSource"); user.setName("jhcode"); user.setPassword("mariaDB"); dao.add(user); System.out.println(user.getId() + " 등록 성공"); User user2 = dao.get(user.getId()); System.out.println(user2.getName()); System.out.println(user2.getPassword()); System.out.println(user2.getId() + " 조회 성공"); } }
- 자바에서 가장 손쉽게 사용 가능한
main()
이용
- 테스트할 대상인
UserDao
객체를 직접 생성하여 메소드 호출
- 테스트에 사용할 입력 값을 직접 setter을 사용해 주입
- 테스트의 결과를 콘솔에 출력
- 예외가 없다면 콘솔에 성공 메세지로 출력
👉
main()
와UserDAO
객체를 직접 호출해서 Test 하였다.—웹을 통한 테스트 방법의 문제점❗
일반적으로 DAO를 테스트하기 위해 모든 계층의 코드를 구현하고 웹에서 직접 테스트하는 경우가 많다. 웹 화면을 통해 값을 입력하고, 결과를 확인하는 방법은 흔히 쓰이지만 아래와 같은 단점을 지닌다.
- 모든 레이어의 기능을 전부 구현해야 한다.
- 테스트 중 에러가 발생하면 어떤 로직에서 에러가 났는지 직접 찾아야 한다. 하나의 기능과 연관된 테스트를 수행하는 데 참여하는 클래스와 코드가 너무 많기 때문이다.
👉웹을 통한 테스트를 하는 방법은 흔히 쓰이지만 위와 같은 문제점이 있다. 그러면 어떻게 조금 더 간편하게 테스트할 수 있을까?
- 자바에서 가장 손쉽게 사용 가능한
✅ unit Test
테스트하고자 하는 대상이 명확하다면, 그 대상에만 집중해서 테스트하는 것이 바람직하다. 테스트는 가능하면 작은 단위로 쪼개서 집중할 수 있어야 해야 테스트에서 문제가 생겼을 때 명확하게 알 수 있다.
UserDaoTest
의 경우는 문제가 생겼을 때 DB 연결 방법, SQL 입력정도에서 문제가 생겼을 것이라고 추측할 수 있다.웹을 통해 테스트를 할 때에 비하면 단위 테스트를 했을 때, 상대적으로 어디서 문제가 생겼는지 명확하게 파악할 수 있다. 내가 구현하고자 하는 특정 기능만 테스트하기 때문이다.
이렇게 작은 단위의 코드에 대해 테스트를 수행하는 것을 단위 테스트(unit test) 라고 한다.
🔹단위 테스트를 하는 이유
- 코드가 계획대로 설계되었는지 검증하기 위해
개발자가 설계하고 만든 코드가 원래 의도한 대로 동작하는지를 개발자 스스로 빨리 확인받기 위해서다. 확인의 대상과 조건은 간단하고 명확할수록 좋다.
단위 테스트는 개발자가 개선한 코드가 처음 설계하고 의도한 대로 바르게 동작했는지를 확인하기 위해 개발자 입장에서 만든 것이기에 개발자 테스트, 프로그래머 테스트라고 부를 수도 있다.
- 자동 수행 테스트 코드
웹 화면을 이용하는 경우, 매번 입력 값을 손으로 입력해주고 버튼을 눌러보아야 한다. 테스트하는데 URL에 접속도 해야하고, 값도 입력해야되서 시간이 많이 소비된다.
반면 UserDaoTest는 main() 메소드를 실행하는 것만으로도 테스트할 수 있게 간단하게 만들어졌다. 이렇게 테스트는 자동으로 수행되도록 만들어야 한다. 또한 테스트용 클래스를 만들어 테스트를 애플리케이션을 구성하는 클래스와 분리시켜, 테스트를 몇 번이고 수행해도 영향을 받지 않게 해야 여러 번 테스트를 수행해도 부담이 없다.
- 지속적인 개선과 점진적인 개발을 위한 테스트
테스트를 통해 DAO코드를 개선할 때마다 해당 기능이 잘 동작하는지 테스트할 수 있었기에 지속적으로 개선할 수 있었다. 만약 전체 로직을 구성하고 테스트를 진행했다면, 수많은 오류에 부딪혀 어디서부터 수정해야할지 감도 잡히지 않았을 것이다. 단위 테스트는 개발자가 짠 코드에 확신을 불어넣어준다.
또한, 기능을 확장할 때도 확장된 기능이 잘 동작하는지 쉽게 확인할 수 있었다. 코드를 개선하고 확장할 때 단위 테스트는 개발자가 짠 코드가 올바르다는 확신을 준다.
—UserDaoTest의 문제점❗
UserDaoTest
는 UI단계까지 동원되는 웹 테스트에 비해 수행하기도 쉽고, 책임도, 관심사도 명확한 클래스였지만, 만족스럽지 못한 부분도 있다.
- 수동 확인 작업의 번거로움
add(), get() 메소드를 통해 가져온 값을 사람이 눈으로 직접 확인해야 했다. 테스트 코드는 값이 일치하는지 확인해주지 않는다. 사람이 검증해야할 양이 많고 복잡해지면 실수를 할 수도 있다. 코드로 테스트 결과가 맞는지 자동으로 확인해주었다면 좋았을 것이다.
- 실행 작업의 번거로움
DAO가 수백 개가 된다면 모든
DaoTest
클래스의main()
메소드를 수백 번 실행하는 상당한 수고가 필요할 것이다. 테스트한 결과를 정리하는데도 큰 시간이 소요된다.
👉이러한 문제를 해결하기 위한 방법으로 Junit Test를 제시한다.
✅ UserDaoTest → Junit Test
프로그래머를 위한 자바 테스팅 프레임워크라고 불리는 JUnit은 테스트 지원 도구이다. 단위 테스트를 만들 때 유용하게 쓸 수 있다.
지금까지 main()
메소드로 실행했던 Test를 Junit Test로 변경해보자. main()
메소드는 제어권을 직접 갖고 있기 때문에 가장 먼저할 일은 main()
메소드에 있는 코드를 다른 일반 메소드로 옮기는 것이다.
JUnit 프레임워크는 @Test 어노테이션과 public 메소드로 되어야한다는 조건이 있다.
- pom.xml
<!-- JUnit Test --> <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.5.0</version> <!-- <scope>test</scope> --> </dependency>
먼저 위와 같이 Junit-jupiter 의존성을 추가해주어야 한다.
- UserDaoTest
package com.jhcode.spring.ch2.dao; import static org.junit.jupiter.api.Assertions.assertEquals; import java.sql.SQLException; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import com.jhcode.spring.ch1.domain.User; public class UserDaoTest { @Test public void addAndGet() throws ClassNotFoundException, SQLException { ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); UserDao dao = context.getBean("userDao", UserDao.class); User user = new User(); user.setId("JUnit"); user.setName("jhcode"); user.setPassword("mariaDB"); dao.add(user); User user2 = dao.get(user.getId()); assertEquals(user2.getName(), user.getName()); assertEquals(user2.getPassword(), user.getPassword()); } }
테스트하고자 하는 메소드는 @Test 어노테이션과 접근제어자 public을 사용했다.
assertEquals()
: JUnit에서 제공하는 메소드로 인자로 받은 두 개의 값을 비교해서 값이 일치하는지 확인해 준다. 객체 배열, 기본 타입 등 모든 유형의 값에 사용할 수 있다.
- JunitTest 실행
UserDaoTest 우클릭 → RunAs → Junit Test 를 실행한다.
테스트가 성공하면 아래와 같은 결과가 나온다.
이것은 IDE에 내장되어 있는 Junit Test를 실행한 것이다. 이 뷰에서는 테스트의 총 수행시간, 실행한 테스트의 수, 테스트 에러의 수, 테스트 실패의 수 등 테스트에 관한 자세한 정보를 알 수 있다.
프로젝트 환경
- IDE : STS3 - 3.9.18.RELEASE
- SpringFramework : 5.3.20
- Java : 11
- Maven
📖토비 스프링 3.1 -p146~161
Uploaded by N2T