이 정도는 알 것이다.
1장에서 했던 UserDaoTest.java 테스트 코드를 개선하는 것이 이번 장의 주제같다.
UserDaoTest.java
public class UserDaoTest {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
UserDao dao = context.getBean("userDao", UserDao.class);
User user = new User();
user.setId("아이디1");
user.setName("이름1");
user.setPassword("비밀번호1");
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() + "조회 성공");
}
}
어디가 문제인지 정확히 파악이 힘들다.
생략..
Test First Development(테스트 우선 개발) 이라고도 한다.
- 개발한 코드의 오류는 빨리 발견할수록 좋다.
- 테스트 없이 오랜 시간 동안 코드를 만들고 나서 테스트를 하면, 오류 발생시 원인 찾기가 쉽지 않다. (예외는 A라는 곳에서 발생하고 사실 원인은 Z였다던지..)
ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
UserDao dao = context.getBean("userDao", UserDao.class);
public class UserDaoTest {
/**
setUp() 메소드에서 만드는 오브젝트를 테스트 메소드에서 사용할 수 있도록 인스턴스 변수로 정의
**/
private UserDao dao;
@Before -> (@Test 메소드가 실행되기 전에 먼저 실행해야 하는 메소드 정의)
public void setUp(){
ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
this.dao = context.getBean("userDao", UserDao.class);
}
...
@Test
public void addAndGet() throws SQLException{
(각 테스트 메소드에 반복적으로 나타났던 코드를 별도의 메소드(@Before)로 옮긴다.)
...
}
@Test
public void count() throws SQLException{
...
dao.get(...)
}
@Test(expected=EmptyResultDataAccessException.class)
public void getUserFailure() throws SQLException{
...
}
}
}
주의점
public class UserDaoTest {
private UserDao dao;
private User user1;
private User user2;
private User user3;
@Before ->
public void setUp(){
...
this.user1 = new User("gyumee", "저팔계", "spring1");
this.user2 = new User("leegw700", "이길원", "spring2");
this.user3 = new User("son", "손오공", "spring3");
}
...
}
}
코드 링크 https://github.com/SpringFrameworkStudy/LeeJooHyun/tree/main/2week/problemDao/version2.3.5/src
UserDaoTest.java
import org.junit.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.dao.EmptyResultDataAccessException;
import java.sql.SQLException;
import static org.hamcrest.CoreMatchers.is;
public class UserDaoTest {
private UserDao dao;
private User user1;
private User user2;
private User user3;
@Before
public void setup(){
ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
this.dao = context.getBean("userDao", UserDao.class);
this.user1 = new User("아이디133", "이름1", "비밀번호1");
this.user2 = new User("leegw700", "이름1", "spring2");
this.user3 = new User("bunjin", "이름이다.", "spring203");
}
@Test
public void addAndGet() throws SQLException, ClassNotFoundException {
dao.deleteAll();
Assert.assertThat(dao.getCount(), is(0));
dao.add(user1);
dao.add(user2);
User userGet1 = dao.get(user1.getId());
Assert.assertThat(userGet1.getName(), is(user1.getName()));
Assert.assertThat(userGet1.getPassword(), is(user1.getPassword()));
User userGet2 = dao.get(user2.getId());
Assert.assertThat(userGet2.getName(), is(user2.getName()));
Assert.assertThat(userGet2.getPassword(), is(user2.getPassword()));
}
@Test
public void count() throws SQLException{
dao.deleteAll();
Assert.assertThat(dao.getCount(), is(0));
dao.add(user1);
Assert.assertThat(dao.getCount(), is(1));
dao.add(user2);
Assert.assertThat(dao.getCount(), is(2));
dao.add(user3);
Assert.assertThat(dao.getCount(), is(3));
}
@Test(expected = EmptyResultDataAccessException.class)
public void getUserFailure() throws SQLException, ClassNotFoundException {
dao.deleteAll();
Assert.assertThat(dao.getCount(), is(0));
dao.get("unknown_id");
}
}
아직 개선해야될 부분이 남아있다.
JUnit은 매번 test class의 오브젝트를 새로 만들지만, test class 전체에 걸쳐 딱 1번만 실행되는 @BeforeClass static method를 지원한다.
-> 하지만 스프링이 직접 제공하는 애플리케이션 테스트 지원 기능이 더 편리하다.
스프링은 JUnit을 이용하는 테스트 컨텍스트 프레임워크를 제공한다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml")
public class UserDaoTest {
@Autowired private ApplicationContext context;
private UserDao dao;
private User user1;
private User user2;
private User user3;
@Before
public void setup(){
this.dao = context.getBean("userDao", UserDao.class);
this.user1 = new User("아이디133", "이름1", "비밀번호1");
this.user2 = new User("leegw700", "이름1", "spring2");
this.user3 = new User("bunjin", "이름이다.", "spring203");
}
@Test
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml")
public class UserDaoTest {
@Autowired private ApplicationContext context;
...
@Before
public void setup(){
this.dao = context.getBean("userDao", UserDao.class);
...
System.out.println(this.context);
System.out.println(this);
}
console :
org.springframework.context.support.GenericApplicationContext@2eafffde (똑같음)
UserDaoTest@29b5cd00
org.springframework.context.support.GenericApplicationContext@2eafffde (똑같음)
UserDaoTest@73ee04c8
org.springframework.context.support.GenericApplicationContext@2eafffde (똑같음)
UserDaoTest@2cd2a21f
스프링 테스트 컨텍스트 프레임워크는 테스트 클래스 안에서 애플리케이션 컨텍스트를 공유해주는 것이 전부가 아니다. 테스트 클래스 사이에서도 애플리케이션 컨텍스트 공유가 가능하다!
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml") <--
public class UserDaoTest {..}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml") <--
public class GroupDaoTest {..}
2022 우정테스트 하기 →→→ https://grandedesafio.com/ko