ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 테스트(1)
    BackEnd/RxJava 2023. 7. 16. 07:00
    반응형

      비동기 처리 결과를 테스트하려면 현재 쓰레드에서 호출 대상 쓰레드의 실행 결과를 반환 받을 때까지 대기할 수 있어야 합니다. RxJava에서는 현재 쓰레드에서 호출 대상 쓰레드의 처리 결과를 받을 수 있는 blockingXXX 함수를 제공합니다. Observable에서 통지되고 가공 처리된 결과 데이터를 현재 쓰레드에 반환하므로, 반환된 결과 값과 예상되는 기대값을 비교해서 단위 테스트를 수행할 수 있습니다.

     

    blockingFirst

    • 생산자가 통지한 첫번째 데이터를 반환합니다.
    • 통지된 데이터가 없을 경우 NoSuchElementException을 발생시킵니다.

    package com.itvillage.section03;
    
    import com.itvillage.common.Car;
    import org.junit.Test;
    
    import static org.hamcrest.CoreMatchers.is;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    
    /**
     * blockingFirst를 사용한 통지된 첫번째 데이터를 테스트하는 예제
     */
    public class BlockingFirstTest {
        // Car 리스트 중에서 첫번째 Car를 테스트
        @Test
        public void getCarStreamFirstTest(){
            // when
            Car car = SampleObservable.getCarStream().blockingFirst();
            String actual = car.getCarName();
    
            // then
            assertThat(actual, is("말리부"));
        }
    
        @Test
        public void getSalesOfBranchAFirstTest(){
            // when
            int actual = SampleObservable.getSalesOfBranchA()
                        .take(6)
                        .blockingFirst();
    
            // then
            assertThat(actual, is(15_000_000));
        }
    }

     

    blockingLast

    • 생산자가 통지한 마지막 데이터를 반환합니다.
    • 통지된 데이터가 없을 경우 NoSuchElementException을 발생시킵니다.
    • 결과를 반환하는 시점이 완료를 통지하는 시점이므로 완료 통지가 없는 데이터 통지일 경우 사용할 수 없습니다.

    package com.itvillage.section03;
    
    import com.itvillage.common.Car;
    import org.junit.Test;
    
    import static org.hamcrest.CoreMatchers.is;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    /**
     * blockingLast를 사용한 통지된 마지막 데이터를 테스트하는 예제
     */
    public class BlockingLastTest {
        // Car 리스트 중 마지막 Car 테스트
        @Test
        public void getCarStreamLastTest(){
            // when
            Car car = SampleObservable.getCarStream().blockingLast();
            String actual = car.getCarName();
    
            // then
            assertThat(actual, is("SM5"));
        }
    
        // A 지점의 월간 매출액 중 6월 달 매출액 테스트
        @Test
        public void getSalesOfBranchALastTest(){
            // when
            int actual = SampleObservable.getSalesOfBranchA()
                        .take(6)
                        .blockingLast();
    
            // then
            assertThat(actual, is(40_000_000));
        }
    }

     

    blockingSingle

    • 생산자가 한 개의 데이터를 통지하고 완료되면 해당 데이터를 반환합니다.
    • 2개 이상의 데이터를 통지할 경우에는 IllegalArgumentException를 발생시킵니다.

    package com.itvillage.section03;
    
    import org.junit.Test;
    
    import static org.hamcrest.CoreMatchers.is;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    /**
     * blockingSingle을 사용한 통지된 첫번째 데이터를 테스트하는 예제
     */
    public class BlockingSingleTest {
    
        // A 지점의 월간 매출 중에 30,000,000원 이상인 매출액의 첫번째 데이터를 테스트
        @Test
        public void totalSalesOfBranchATest(){
            int actual = SampleObservable.getSalesOfBranchA()
                                .filter(sale -> sale > 30_000_000)
                                .take(1)
                                .blockingSingle();
    
            assertThat(actual, is(35_000_000));
        }
    
        // A 지점의 월간 매출 중에 30,000,000원 이상인 매출액의 첫번째 데이터를 테스트
        @Test(expected = IllegalArgumentException.class)
        public void totalSalesOfBranchATest2(){
            SampleObservable.getSalesOfBranchA()
                    .filter(sale -> sale > 30_000_000)
                    .take(2)
                    .blockingSingle();
        }
    }

     

    blockingGet

    • 생산자가 0개 또는 1개의 데이터를 통지하고 완료되면 해당 데이터를 반환합니다.
    • 즉, 생산자가 Maybe일 경우 사용할 수 있습니다.

    package com.itvillage.section03;
    
    import io.reactivex.Observable;
    import org.junit.Test;
    
    import static org.hamcrest.CoreMatchers.is;
    import static org.hamcrest.CoreMatchers.nullValue;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    /**
     * blockingGet을 사용한 통지 데이터 테스트 예제
     */
    public class BlockingGetTest {
        @Test
        public void blockingGetEmptyTest(){
            // then
            assertThat(Observable.empty().firstElement().blockingGet(), is(nullValue()));
        }
    
        // A 지점의 월간 매출 합계 테스트
        @Test
        public void totalSalesOfBranchATest(){
            // when
            int totalSales = SampleObservable.getSalesOfBranchA()
                    .reduce((a, b) -> a + b)
                    .blockingGet();
    
            // then
            assertThat(totalSales, is(326_000_000));
        }
    
        // A, B, C 지점의 연간 매출 합계 테스트
        @Test
        public void salesAllBranchTest(){
            // when
            int totalSales = Observable.zip(
                    SampleObservable.getSalesOfBranchA(),
                    SampleObservable.getSalesOfBranchB(),
                    SampleObservable.getSalesOfBranchC(),
                    (a, b, c) -> a + b + c
                )
                .reduce((a, b) -> a + b)
                .blockingGet();
    
            // then
            assertThat(totalSales, is(992_000_000));
    
        }
    }

     

    blockingIterable

    • 생산자가 통지한 모든 데이터를 받을 수 있는 Iterable을 얻게 합니다.
    • 구독 후 Iterable의 next() 메서드를 호출하는 시점부터 처리합니다.

    package com.itvillage.section03;
    
    import com.itvillage.common.CarMaker;
    import org.junit.Test;
    
    import java.util.Iterator;
    
    import static org.hamcrest.CoreMatchers.is;
    import static org.hamcrest.MatcherAssert.assertThat;
    /**
     * blogkingIterable을 사용한 통지 데이터 테스트 예제
     */
    public class BlockingIterableTest {
        // 전체 CarMaker의 요소가 맞는지 모두 테스트한다.
        @Test
        public void getCarMakerIterableTest() {
            // when
            Iterable<CarMaker> iterable = SampleObservable.getCarMakerStream()
                    .blockingIterable();
    
            Iterator<CarMaker> iterator = iterable.iterator();
    
            // then
            assertThat(iterator.hasNext(), is(true));
    
            assertThat(iterator.next(), is(CarMaker.CHEVROLET));
            assertThat(iterator.next(), is(CarMaker.HYUNDAE));
            assertThat(iterator.next(), is(CarMaker.SAMSUNG));
            assertThat(iterator.next(), is(CarMaker.SSANGYOUNG));
            assertThat(iterator.next(), is(CarMaker.KIA));
    
        }
    }

     

    blockingForEach

    • 생산자가 통지한 데이터를 순차적으로 모두 통지합니다.

    package com.itvillage.section03;
    
    import org.junit.Test;
    
    import static org.hamcrest.Matchers.greaterThan;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    /**
     * blockingForEach를 사용해 통지된 데이터 전부를 테스트 한다.
     */
    public class blockingForEachTest {
        // A 구간의 속도 중에서 110 이상인 속도만 필터링이 되었는지 테스트
        @Test
        public void getSpeedOfSectionAForEachTest() {
            SampleObservable.getSpeedOfSectionA()
                    .filter(speed -> speed > 110)
                    .blockingForEach(speed -> assertThat(speed, greaterThan(110)));
        }
    }

     

    blockingSubscribe

    • 통지된 원본 데이터를 호출한 원본 쓰레드에서 부수적인 처리를 할 수 있도록 해줍니다.
    • 소비자가 전달 받은 데이터로 어떤 부수적인 처리를 할 때 이 처리 결과를 테스트 할 수 있습니다.

    package com.itvillage.section03;
    
    import org.junit.Test;
    import static org.hamcrest.CoreMatchers.is;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    /**
     * blockingSubscribe를 사용해 구독 후 소비자의 처리로 인해 부수 작용이 발생한 결과를 테스트하는 예제
     */
    public class BlockingSubscribeTest {
    
        // A 지점의 월간 매출 합계를 부수 작용으로 테스트
        @Test
        public void avgTempOfSeoulTest() {
            Calculator calculator = new Calculator();
    
            SampleObservable.getSalesOfBranchA()
                    .blockingSubscribe(data -> calculator.setSum(data));
    
            assertThat(calculator.getSum(), is(326_000_000));
        }
    }

     

     

     

    [참고 자료]

    반응형

    'BackEnd > RxJava' 카테고리의 다른 글

    테스트(2)  (0) 2023.07.16
    디버깅(Debugging)  (0) 2023.07.15
    스케쥴러(Scheduler)  (0) 2023.07.15
    Subject  (0) 2023.07.14
    집계 연산자  (0) 2023.07.13

    댓글

Designed by Tistory.