RxJava2, RxAndroid2

[RxJava2] JUnit 5 + RxJava2 로 테스트 코드 짜기

알통몬_ 2018. 10. 12. 11:25
반응형


공감 및 댓글은 포스팅 하는데

 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 

도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 

만들어 나가겠습니다^^

 



이번 포스팅에서는 Java의 JUnit 5 와 RxJava2를 사용해

테스트 코드를 짜보겠습니다.


테스트의 중요성

SW 의 품질은 테스트에서 결정되는데요.

때문에 테스트 주도 개발이라는 개발 방법론까지 있을 정도로

코드가 정상적으로 동작하는지 검증하는 테스트 코드는 중요합니다.


현재 자바에서 테스트 코드를 작성하는 가장 유명한 라이브러리가

제목처럼 JUnit 인데요. 현재 JUnit 5 버전까지 릴리즈 되었습니다.


테스트 코드 작성 환경은

이클립스 최신 버전인 PHOTON 버전입니다.

메이븐 프로젝트를 만들어주시고 pom.xml 파일에

JUnit 사용을 위한 아래 3개의 의존성과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.2.0</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.2.0</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-runner -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-runner</artifactId>
            <version>1.2.0</version>
            <scope>test</scope>
        </dependency>
 
cs

RxJava 사용을 위한

1
2
3
4
5
6
        <dependency>
            <groupId>io.reactivex.rxjava2</groupId>
            <artifactId>rxjava</artifactId>
            <version>2.2.1</version>
        </dependency>
 
cs

위 의존성까지 추가해주면 됩니다.


그리고 이클립스에서는 기본으로 JUnit4 가 설정되어 있기 때문에

5를 사용하려면 약간의 설정이 필요합니다.


프로젝트 우클릭 -> Build Path -> Configure Build Path 

Libraries 탭의 JUnit 4를 5로 바꿔주시고

Order and Export 탭의 가장 아래 JUnit 5 를 체크해줍니다.


JUnit 5 만 사용한 테스트 코드 예제)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
 
@RunWith(JUnitPlatform.class)
public class FirstJUnitTest {
 
    @DisplayName("junit 5 1st ex")
    @Test
    void testMethod() {
        int a = 3;
        int b = + 2;
        assertEquals(a, b);
    }
}
 
cs

@RunWith(JUnitPlatform.class)

: JUnit 5가 아직 이클립스를 완벽히 지원하지 않아서 Runner 클래스를 지정해야 함.

@DisplayName("name")

: 테스트를 구분할 때 사용, 공백

@Test

: 해당 메서드가 테스트 코드임을 명시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
 
@RunWith(JUnitPlatform.class)
public class FirstJUnitTest {
 
    @DisplayName("junit 5 1st ex")
    @Test
    void testMethod() {
        int a = 3;
        int b = + 2;
        assertEquals(a, b);
    }
}
 
cs


Observable 과 JUnit 5 혼용

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
import static org.junit.Assert.assertEquals;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
 
import io.reactivex.Observable;
 
@RunWith(JUnitPlatform.class)
public class FirstJUnitTest {
 
    @DisplayName("test Observable of RxJava2")
    @Test
    void testObservable() {
        String[] strs = { "1""1-A""1-B" };
 
        Observable<String> src = Observable.fromArray(strs).map(FirstJUnitTest::getType);
 
        String[] expect = { "none""type-A""type-B" };
 
        List<String> actuals = new ArrayList<>();
        src.doOnNext(System.out::println).subscribe(actuals::add);
 
        assertEquals(Arrays.asList(expect), actuals);
 
    }
 
    static String getType(String str) {
        switch (str) {
        case "1":
            return "none";
        case "1-A":
            return "type-A";
        case "1-B":
            return "type-B";
        default:
            return "0";
        }
 
    }
 
}
 
cs


[ 광고 보고 가시죠! ]



[ 감사합니다! ]


TestObserver 클래스 사용

RxJava2 에서 제공하고 있는 TestObserver 클래스를 활용한 테스트 코드

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
62
63
64
65
import static org.junit.Assert.assertEquals;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
 
import io.reactivex.Observable;
 
@RunWith(JUnitPlatform.class)
public class FirstJUnitTest {
 
@DisplayName("use TestObserver")
    @Test
    void testObserver() {
        String[] strs = { "1""1-A""1-B" };
 
        Observable<String> src = Observable.fromArray(strs).map(FirstJUnitTest::getType);
 
        String[] expect = { "none""type-A""type-B" };
        
        src.test().assertResult(expect);
    }
 
    @DisplayName("use TestObserver2")
    @Test
    void testObserver2() {
        String[] strs = { "100""200""1-B" };
 
        Observable<Integer> src = Observable.fromArray(strs).map(Integer::parseInt);
 
        //src.test().assertFailure(NumberFormatException.class, 100,200);
        src.test().assertFailureAndMessage(NumberFormatException.class"For input String: \"1-B\""100200);
    }
    
    @DisplayName("use TestObserver3")
    @Test
    void testObserver3() {
        Observable<String> src = Observable.<String>create(emit -> {
            emit.onNext("Hello JUnit N RxJava2");
            emit.onComplete();
        });
        src.test().assertComplete();
    }
 
    static String getType(String str) {
        switch (str) {
        case "1":
            return "none";
        case "1-A":
            return "type-A";
        case "1-B":
            return "type-B";
        default:
            return "0";
        }
 
    }
 
}
 
cs

testObserver() :

test().assertResult()

예상된 결과와 실제 결과를 비교하는 메서드.

JUnit 의 assertEquals() 와 같은 기능.


testObserver2():

assertFailure(error, 예측값들)

assertFailureAndMessage(error, errorMsg, 예측값들)

에러가 발생했을 경우 

error : 발생할 것으로 예상되는 에러 클래스

errorMsg : 사용자에게 알려줄 에러 메시지

예측값들 : 결과 예측 값들.

testObserver2() 의 경우는 실패하는 테스트 코드인데

실패하는 테스트 코드들을 무시할 수 있는 Annotation이 있습니다.

1
2
3
4
5
6
7
    @DisplayName("use TestObserver2")
    @Test
    @Disabled
    void testObserver2() {
          .........
    }
 
cs

@Disabled를 써주면 해당 테스트는 무시하고 진행합니다.


testObserver3():

assertComplete()

테스트하는 Observable이 정상적으로 완료되었는지 확인하는 메서드.

assertComplete()과 반대되는 assertNotComplete()도 제공합니다.


*test 코드 .java 파일들은

src/test/java 아래에 파일을 두고 테스트하셔야 합니다.

다음 포스팅에서는 비동기 코드를 테스트 하는 방법에 대해 간단히 포스팅합니다.

감사합니다.





반응형