테스트는 스프링을 학습하는데 가장 효과적인 방법이다.

실제 프로젝트를 하다보면 테스트가 얼마나 중요한지 느끼게 된다. 실제 개발자들 중 테스트를 거치지 않고 서버에 소스를 commit하는 경우는 없을 것이다. 스프링에서는 개발자들이 쉽게 사용할수 있도록 테스트 기능을 제공해준다. 

지금부터, 스프링의 강력한 기능중에 하나인 test에 대해서 공부해 보자. 

테스트는 가능하면 가장 작은 단위로 쪼개어 수행해야 한다. 이렇게 작은 단위의 코드에 대해 테스트를 수행 하는 것을 단위 테스트(UNIT TEST) 라고 한다.   여기서 단위의 의미는 코딩할때  각 수행 logic별로 method를 나누어 구현 하는데, 이때, 이 method정도의 크기를 말하는 것이라 이해했다. 

자바에서는 JUnit이라는 자바 테스팅 프레임워크를 제공한다. 자바로 단위테스트를 만들때 유용하게 쓸수있다. 

JUnit 테스트는 아래의 7단계로 간략화 할수 있다.  


  1. 테스트 클래스에서 @Test가 붙은 public이고 void형이며 파라미터가 없는 테스트 메소드를 모두 찾는다.
  2. 테스트 클래스의 오브젝트를 하나 만든다.
  3. @Before가 붙은 메소드가 있으면 실행한다.
  4. @Test가 붙은 메소드를 하나 호출하고 테스트 결과를 저장해둔다. 
  5. @After가 붙은 메소드가 있으면 실행한다. 
  6. 나머지 테스트 메소드에 대해 2-5번을 반복한다. 
  7. 모든 테스트의 결과를 종합해서 돌려준다. 

여기서 한가지 주의할점은 @Test가 붙은 메소드를 실행할때 마다 매번 새로운 오브젝트를 만든다는 것이다. 

즉, 하나의 테스트 클래스안에 @Test가 붙은 메소드가 2개 라면 2개의 오브젝트가 만들어진다는 것이다.  이로써, 각 테스트가 서로 영향을 주지않고 독립적으로 실행됨을 보장 받을수 있다. 

지금부터 JUnit사용법을 배워보자. 

JUnit 프레임 워크에서 동작 하기 위해서는 아래 두조건을 꼭 지켜야 한다.  

  •    테스트 하고자 하는 Method에 @Test 라는 Annotation을 붙여줄것
  •    public이며 void형으로 선언할것.

아래 예제를 보자.  addAndGet메소드를 테스트 하기로 했다면 해당 메소드위에 @Test Annotaion을 붙이고 

해당 메소드를 public void형으로 선언 해둬야 한다. JUnit은 public메소드만을 테스트 메소드로 허용한다. 

@Test 
public void addAndGet() throws SQLException {
ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
UserDao dao = context.getBean("userDao", UserDao.class);

User user = new User();
user.setId("gyumee");
user.setName("박성철");
user.setPassword("springno1");

dao.add(user);

User user2 = dao.get(user.getId());

assertThat(user2.getName(), is(user.getName()));
assertThat(user2.getPassword(), is(user.getPassword()));
}

테스트시 유용하게 사용할 수 있는 JUnit  Static method 가 있다. 

 >> assertThat :  JUnit에서 제공하는 if 문장의 기능을 하는 함수로 첫 파라미터 값을  두번째 파라미터의 조건과 일치하면 넘어가고, 다르면 테스트가 실패하도록 만들어준다. 

    assertThat(user2.getName(), is(user.getName()));  

  -> user2.getName()와 user.getName()일치하는지 체크

  -> is()는 matcher의 일종으로  equals()로 비교해주는 기능을 가짐  

자.. 그럼 테스트를 위한 Application Context관리는 어떻게 해줘야 할까?

테스트 서버와 실제 사용서버가 다르듯이 테스트 Application Context를 따로 만들어 주는 것이 좋다. 

그리고 매번 @Test가 붙은 Method을 실행할때 마다 객체를 다시 만들기 때문에 ApplicationContext를 만드는 코드를 

아래 코드와 같이 테스트 메소드 안에 직접 명시하는 것은 좋지 않다. 

@Test 
public void andAndGet() throws SQLException {

  ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
  UserDao dao = context.getBean("userDao", UserDao.class);

  dao.deleteAll();
  assertThat(dao.getCount(), is(0));

  User user = new User();
  user.setId("gyumee");
  user.setName("박성철");
  user.setPassword("springno1");

  dao.add(user);
  assertThat(dao.getCount(), is(1));

  User user2 = dao.get(user.getId());

  assertThat(user2.getName(), is(user.getName()));
  assertThat(user2.getPassword(), is(user.getPassword()));
}

이런경우, 아래 소스에서 처럼 @Autowired Annotation 을 써주면 된다.  @Autowired Annotation가 붙은 인스턴스 변수가 있으면 테스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스 내의 빈을 찾아준다. 그리고 스프링 어플리케이션은 초기화 할때 자기 자신도 빈으로 등록해 둔다. 따라서, 해당 테스트 클래스 실행시에 스프링 어플리케이션은 @Autowired가 붙은 context에 해당 객체를 찾아서 던져주게 된다. 즉,  ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); 와 같은 효과를 가질수 있다. 

@RunWith(SpringJUnit4ClassRunner.class)  // 스프링의 테스트 컨텍스트 프레임워크의 JUnit확장 기능 지정 
@ContextConfiguration(locations="/applicationContextTest.xml") // 테스트 컨텍스트가 자동으로 만들어줄 어플리
public class UserDaoTest {                                                            케이션 컨텍스트의 위치 지정 
  @Autowired 
   private ApplicationContext context; 
  UserDao dao; 
  User user1,user2,user3; 

  @Before 
  public void setUp() { 
  dao=this.context.getBean("userDao",UserDao.class); 
  user1 = new User("gyumee", "박성철", "springno1"); 
  user2 = new User("leegw700", "이길원", "springno2"); 
  user3 = new User("bumjin", "박범진", "springno3"); 
  ..................

  ..................
}

그리고  여기서 주의 할 점은  테스트 클래스 상단에 아래 두 Annotation을 지정해 줘야 한다. 


      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(locations="/applicationContextTest.xml")


@ RunWith은 JUnit의 프레임워크의 테스트 실행방법을 확장할 때 사용하는 Annotaion이다. SpringJUnit4ClassRunner.class라는 JUnit의 확장 클래스를 지정해 주면 JUnit이 테스트를 진행하는 중에 테스트가 사용할 Application Context를 만들고 관리하는 작업을 진행해준다. 

@ContextConfiguration은 자동으로 만들어줄 Application Context의 설정파일 위치를 지정한다. 

2장 테스트는 여기서 마무리 하겠다. .......................

+ Recent posts