본문으로 바로가기

[스프링/Spring] JUnit Test

category Spring 스프링 2018. 11. 23. 12:50
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



 JUnit은 단위 테스트 도구이다. 기존에 System.out.println()으로 하나하나 로그를 찍거나, Debug를 하지 않아도 JUnit Test Case를 작성하여 쉽게 단위 테스트를 할 수 있다. Junit은 플러그인 형태로 Eclipse에 포함되어 있고, Spring에서는 pom.xml에 의존성을 추가하여 쉽게 단위 테스트를 시행할 수 있다. JUnit은 보이지 않고 숨겨진 단위테스트를 끌어내어 졍형화시켜 단위테스트를 쉽게 해주는 테스트용 FrameWork이다.


JUnit의 특징


1. 단위테스트 Framework이다.

2. 문자 혹은 GUI 기반으로 실행된다.

3. 어노테이션으로 간결하게 사용할 수 있다.

4. 결과는 성공(녹색), 실패(붉은색) 둘 중에 하나로 표시된다.

5. 단정문으로 테스트 케이스의 수행 결과를 판별한다.

 

@Test 어노태이션


@Test 어노테이션이 적용된 메서드는 단위 테스트 메소드임을 지정한다는 것이다.

@Test(timeout=5000) 시간 단위는 밀리초이고, 테스트 메소드 결과가 5초를 넘기면 테스트는 실패한다.

@Test(expected=RuntimeException.class) 테스트 실행 도중 RuntimeException이 발생해야 테스트가 성공, 그렇지 않으면 실패이다.


@Before @After 어노태이션


메서드 위에 해당 어노테이션이 선언되면 테스트 클래스 안에 메소드들이 테스트 되기 전과 후에 각각 실행되게 지정하는 어노테이션이다.

@Before는 @Test 메서드가 실행될 때마다 객체가 생성되고 실행된다. 쉽게 말해서 @Test 메서드가 3개라면 3번 실행하기 위해 객체 생성을 3번한다.

@Before메서드는 @Test 메서드가 실행되기 전에 반드시 실행하게 된다. @Test메서드마다 공통으로 사용하는 데이터를 @Before메서드에서 실행하는 것인다. 여기서 공통으로 사용하는 데이터를 fixture라고 한다.


@BeforeClass @AfterClass 어노태이션


@BeforeClass @AfterClass가 메서드 위에 선언되면 해당 테스트 클래스에서 딱 한 번씩만 수행되도록 지정하는 어노테이션 이다. 위 두개의 어노테이션은 메서드가 static 이어야 한다.

@BeforeClass는 @Before에서 설명했듯이 @Test 메서드 실행 할 때마다 객체를 생성한다고 설명했는데, 이때 생성되는 객체가 최초에 한번만 실행되는 어노테이션이다.



JUnit의 호출 순서는 아래와 같다.


이미지 참고 : http://www.nextree.co.kr/p11104/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@BeforeClass
 
@Before
@Test
@After
 
@Before
@Test
@After
 
@Before
@Test
@After
 
@AfterClass 



@Ignore

@Ignore 어노테이션이 적용된 메서드는 단위 테스트를 실행하지 않는다.


대표적인 assert단정문


assertArrayEquals(A,B) : 배열 A, 배열B가 일치하는지 확인한다.

assertEquals(A,B) : 객체 A, B의 값이 같은지 확인한다.

assertSame(A,B) : 객체A, B가 같은 객체인지 확인한다.

assertTrue(A) : A가 True인지 확인한다.

assertNotNull(A) : A객체가 null이 아닌지 확인한다.


이 외에도 다양한 assert 메서드들이 존재한다. JUnit API 보기 에 들어가서 확인하면 된다.


스피링에서 JUnit 사용하기 


스프링에서 테스트할 때 bean에 등록된 객체들을 @Autowired나 @Inject 어노테이션을 사용해야 할 때가 있다. 이 때 16 ~ 17 라인에 있는 어노테이션들이 필요하다. 17 라인의 @ContextConfiguration은 스프링에서 선언된 bean들의 값을 @Autowired나 @Inject 등등을 통해 사용해야할 때 필요하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import static org.junit.Assert.assertEquals;
 
import java.util.List;
 
import javax.inject.Inject;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
import com.ktko.common.Common;
import com.ktko.service.ToDoService;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml" })
public class CommonTest {
    
    @Inject
    private ToDoService service;
    
    @Autowired
    private Common common;
    
    //문자열 확인 하기
    @Test
    public void getTodoRefCheck() {
        List<Integer> list = common.getTodoRef("할일 @1 @2 @3");
        assertEquals(list.size(),3);
    }
    
    //할일이 수정되거나 입력될 때 존재하지 않는 참조 값일 경우 true, false 리턴 
    @Test
    public void checkTodoRef() {
        int totalTodo = service.getTotalTodoCount();
        
        List<Integer> list = common.getTodoRef("할일 @1 @2 @3");
        boolean check1 = common.checkTodoRef(totalTodo, list);
        assertEquals(check1, true);
        
        list = common.getTodoRef("할일 @1 @2 @3 @66");
        boolean check2 = common.checkTodoRef(totalTodo, list);
        assertEquals(check2, false);
    }
    
    @Test
    public void checkDateFormat() {
        String check1 = "1989-07-14";
        String check2 = "1989-071-14";
        
        assertEquals(common.checkDateFormat(check1), true);
        assertEquals(common.checkDateFormat(check2), false);
    }
}



JUnit 예제 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import com.ktko.exception.NoParameterType;
 
public class CalCulator {    
    public int sum(int a, int b) {
        
        return a+b;
    }
    
    public int subtract(int a, int b) throws NoParameterType {
        
        if(a < b) {
            throw new NoParameterType();
        }
        
        return a-b;
    }
    
    public int absoluteVal(int a) {
        
        return Math.abs(a);
    }
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
 
import com.ktko.common.CalCulator;
import com.ktko.exception.NoParameterType;
 
public class CalculateTest {
    private static CalCulator cal = null;
    
    @Before
    public void beforeMethod() {
        System.out.println("@Before");
    }
    
    @After
    public void afterMethod() {
        System.out.println("@After");
    }
    
    @BeforeClass
    public static void beforeClass() {
        System.out.println("@BeforeClass");
        cal = new CalCulator();
    }
    
    @AfterClass
    public static void afterClass() {
        System.out.println("@AfterClass");
    }
    
    @Test
    public void add() {
        System.out.println("@Test add");
        int result = cal.sum(1,2);
        Assert.assertEquals(3, result);
    }
    
    @Test
    public void subtract() throws NoParameterType {
        System.out.println("@Test substract");
        int result = cal.subtract(42);
        Assert.assertEquals(2, result);
    }
    
    @Test(expected=NoParameterType.class)
    public void NoParameterTypeException() throws NoParameterType {
        System.out.println("@Test substract");
        int result = cal.subtract(24);
        Assert.assertEquals(2, result);
    }
    
    @Test
    public void absoluteVal() {
        System.out.println("@Test absoluteVal");
        Assert.assertEquals(4, cal.absoluteVal(-4));
    }
}