인프런 커뮤니티 질문&답변

덩더러러쿨님의 프로필 이미지

작성한 질문수

Kevin의 알기 쉬운 RxJava 2부

RxJava의 API를 사용하지 않은 테스트 코드의 문제점에 대한 추가 설명

조금 더 자세한 설명부탁드립니다

해결된 질문

작성

·

237

0

해당 강의에서 추가 설명에 대해 이해가 되지 않아서 조금 더 자세한 설명 부탁드립니다.

우선, 제가 임의로 아래 코드처럼 main 스레드를 0.5초 동안 일시 정지를 적용 시켜보았더니 정상적으로 동작했습니다.

- UnitTestNotByRxJava.java (Test)

public class UnitTestNotByRxJava {
@Test
public void getCarMakerStreamSyncTest(){
List<CarMaker> carMakerList = new ArrayList<>();
SampleObservable.getCarMakerStream()
.subscribe(data -> carMakerList.add(data));

TimeUtil.sleep(500L);
assertThat(carMakerList.size(), is(5));
}
}

- SampleObservable.java

public class SampleObservable {
...
public static Observable<CarMaker> getCarMakerStream() {
Observable<CarMaker> observable =
Observable.fromArray(SampleData.carMakers)
.subscribeOn(Schedulers.computation());
return observable;
}
...
}

즉, 기존 예제에서 오류가 나는 이유가, main 스레드와 호출 함수 getCarMakerStream 내 'RxComputationThreadPool' 스레드가 동시에 실행이 되어 그 짧은 시간 사이에 main 스레드에서 결과 값을 리턴받지 못하기 때문이다라고 이해하면 될까요?

답변 2

1

Kevin님의 프로필 이미지
Kevin
지식공유자

안녕하세요? 질문 주신 부분에 대해서 답변을 드리겠습니다.

"즉, 기존 예제에서 오류가 나는 이유가, main 스레드와 호출 함수 getCarMakerStream 내 'RxComputationThreadPool' 스레드가 동시에 실행이 되어 그 짧은 시간 사이에 main 스레드에서 결과 값을 리턴받지 못하기 때문이다라고 이해하면 될까요?" 

말씀하신 내용과 거의 비슷한데요. main 쓰레드와 RxComputationThreadPool 쓰레드가 동시에 실행되는 것이 아니라 RxComputationThreadPool 쓰레드에서 실행되는 RxJava 코드보다 main 쓰레드에서 실행되는 assertThat 코드가 먼저 실행이 되기때문에 테스트에 실패하는것입니다.

그래서 질문자님이 0.5초 딜레이를 준 그 시점에는 아래쪽 assertThat 코드가 실행이 되지 않고, 윗쪽의 RxJava 코드가 먼저 실행이 되는 것입니다.

답변이 충분한지 모르겠네요. ^^;

0

답변 감사합니다!

제가 test가 아닌 환경에서 해당 예제를 가지고 assertThat( ) 메소드를 제외하고 실행시켜 보아도 subscribe( ) 메소드에 결과가 나오지 않더라구요

이것도 RxComputationThreadPool로부터의 데이터를 통지도 하기 전에 main 스레드에서의 작업이 끝나서 결과 값이 안나온 것이군요?

List<CarMaker> carMakerList = new ArrayList<>();
SampleObservable.getCarMakerStream()
.map(data -> carMakerList.add(data))
.subscribe(data -> Logger.log(LogType.ON_NEXT, carMakerList));

// TimeUtil.sleep(1000L);

- 스레드 지연 시간 적용 시 결과

onNext() | RxComputationThreadPool-1 | 22:51:26.875 | [CHEVROLET]
onNext() | RxComputationThreadPool-1 | 22:51:26.877 | [CHEVROLET, HYUNDAE]
onNext() | RxComputationThreadPool-1 | 22:51:26.877 | [CHEVROLET, HYUNDAE, SAMSUNG]
onNext() | RxComputationThreadPool-1 | 22:51:26.878 | [CHEVROLET, HYUNDAE, SAMSUNG, SSANGYOUNG]
onNext() | RxComputationThreadPool-1 | 22:51:26.878 | [CHEVROLET, HYUNDAE, SAMSUNG, SSANGYOUNG, KIA]
Kevin님의 프로필 이미지
Kevin
지식공유자

"이것도 RxComputationThreadPool로부터의 데이터를 통지도 하기 전에 main 스레드에서의 작업이 끝나서 결과 값이 안나온 것이군요?"

네, 맞습니다. 그렇기때문에 interval( ) 연산자의 경우 디폴트 실행 쓰레드가 main 쓰레드가 아니기때문에 main 쓰레드에 약간의 지연 시간을 주어야 정상적으로 실행이 됩니다.

감사합니다!