spring 비동기 테스트

greenTea·2023년 12월 13일
0

🫠스프링에서는 비동기 로직을 테스트하기 위해 StepVerifier라는 클래스를 제공하고 있습니다.

이를 통해 다양한 비동기 로직을 테스트할 수 있습니다.

1. Block 방식으로 테스트하는 방법과 문제점

😎가장 먼저 비동기 방식을 테스트하기 위해서 block()을 이용해서 비동기 로직을 끝내고 난 후에 데이터를 받아와서 처리하는 방법이 있습니다.

	@DisplayName("blocking")
	@Test
	void blocking() {
		String data = Mono.just("data")
						  .block();

		assertEquals(data,"data");

	}

😰그러나 위 방식은 몇가지 문제를 가지고 있는데...

  • 블로킹: block() 메소드는 스트림이 완료될 때까지 현재 스레드를 블로킹합니다.
  • 시간 소모: 큰 데이터셋이나 복잡한 파이프라인에서는 완료 시간이 길어질 수 있습니다. delayElements()와 같은 경우이거나 로직이 1시간 이상이 걸리는 로직의 경우 테스트를 하는데에 많은 제약이 걸리게 됩니다.
  • 테스트의 정확성: block()은 최종 결과만을 반환하기 때문에, 스트림이 어떻게 동작하는지에 대한 검증이 어렵습니다.

위와 같은 문제를 해결하기 위해 StepVerifier라는 것이 나왔습니다.

2. StepVerifier 사용 예제

🫡StepVerifier를 사용하면 스트림의 각 단계를 세밀하게 검증할 수 있습니다. 예를 들어:

Flux<String> flux = Flux.just("1", "2", "3");

StepVerifier.create(flux)
    .expectNext("1")
    .expectNext("2")
    .expectNext("3")
    .expectComplete()
    .verify();

이 코드는 flux가 "1", "2", "3"를 순서대로 방출하고 완료되는지 검증합니다.

	void fluxTest() {
		Flux<Integer> flux = Flux.range(0, 10);

		StepVerifier.create(flux)
			.expectNextCount(6)
			.expectNext(6,7,8,9)
			.expectComplete()
			.verify();
	}

expectNextCount()를 통해 6번의 next가 발생했다는 것을 검증하였으며 이후에는 6,7,8,9가 차례대로 오는지 확인합니다.

void fluxTest2() {

Mono<Object> errorMono = Mono.error(RuntimeException::new);

StepVerifier.create(errorMono)
.verifyErrorSatisfies(e -> {
						Assertions.assertInstanceOf(RuntimeException.class,e);
					});
	}

verifyErrorSatisfies()를 통해 에러가 발생하는지도 검증을 할 수 있습니다.

3. Delay 사용 시 테스트 방법

🤓delayElements와 같은 지연을 포함하는 스트림을 테스트할 때는 StepVerifierwithVirtualTime을 사용할 수 있습니다. 이를 통해 실제 시간을 기다리지 않고도 시간에 기반한 동작을 테스트할 수 있습니다.

StepVerifier.withVirtualTime(() -> Mono.just(1).delayElement(Duration.ofHours(10L)))
					.expectSubscription()
					.thenAwait(Duration.ofHours(12L))
					.expectNext(1)
					.expectComplete()
					.verify();

mono.just(1)을 통해 1이라는 값이 들어간 mono를 만듭니다. 이 후 10시간의 delay를 가진 후에 방출하도록 하였습니다.

만약 StepVerifier가 없었다면 하나의 테스트가 10시간 이상을 잡아먹는 상황이 되지만 StepVerifier.withVirtualTime()를 통해 가상으로 시간을 지나게 한 상황을 만들어서 확인할 수 있게 되었습니다.

thenAwait()를 통해 원하는 시간 만큼 시간을 지나게 하였으며 그렇게 되면 이미 10시간을 넘은 상황이므로 테스틑 성공하게 됩니다.

thenAwait()안 시간을 9L로 하고 실행해보면 테스트가 계속 진행 상태가 됩니다

마무리

🥳위와 같이 StepVerifier를 사용한다면 각 단계별로 검증을 할 수 있습니다. 위 메소드 외에도 다양한 메소드들이 존재하며 더욱 세분화시켜서 Assertions와 같은 검증 메소드와 함께 사용한다면 더욱 구체적으로 스트림을 검증할 수 있습니다.

참고자료

Spring Webflux 완전 정복 : 코루틴부터 리액티브 MSA 프로젝트까지

profile
greenTea입니다.

0개의 댓글