새소식

반응형
Spring/etc

[Spring] spring-retry 재시도 with TestCode

  • -
반응형

 

순단과 같은 네트워크 에러가 가끔 발생하는 부분에 대한 처리를 어떻게 해야 할지 고민하는 도중 spring-retry를 발견하게 되었고, 간편하게 retry 로직을 수행할 수 있을 것 같아 학습하고 적용해 보았다.

 

Spring project

 

Dependency

implementation("org.springframework.retry:spring-retry")
implementation("org.springframework:spring-aspects")

 

@EnableRetry

@Configuration
@EnableRetry
public class MyConfig { 
    ... 
}

 

@Retryable

    @Retryable(
        include = RuntimeException.class,
        exclude = DataAccessException.class,
        maxAttempts = 5, 
        backoff = @Backoff(2000L),
        recover = "recoverTest"
    )
    public void test(Dto dto) {
        // ...
    }

    @Recover
    public void recoverTest(RuntimeException e, Dto dto) {
        // ...
    }

 

@Retryable attributes

  • maxAttempts
    • 최대 재시도 횟수
    • defaults 3
  • backoff
    • 다음 수행까지 delay time
    • defaults 1000ms
  • include(retryFor) 
    • retry를 수행할 특정 에러 지정
    • defaults : all exception
  • exclude
    • retry를 수행하지 않을 특정 에러 지정
  • recover
    • maxAttempts 이후에 도달했을 때 수행하는 로직 지정

 

Test Code

maxRetryAttempt를 3번이라고 설정해 둔 코드를 테스트한다고 하면

BDDMockito를 통해서 2번은 Exception을 던지고 한 번은 성공 처리를 할 수 있다

최종적으로 test method의 로직이 3번 호출되었는지 확인하는 식으로 테스트를 작성할 수 있다. 

    @Test
    void test() {
        // given
        Dto dto = generateDto();
        BDDMockito.willThrow(new RuntimeException("", new Exception()))
                  .willThrow(new RuntimeException("", new Exception()))
                  .willDoNothing()
                  .given(myRepository).test(Mockito.any());

        // when
        sut.test(dto);

        // then
        Mockito.verify(myRepository, Mockito.times(3)).test(Mockito.any());
    }

 

이와 반대로 지속적으로 에러가 발생하도록 하여 테스트 코드를 작성할 수도 있다.

지속적으로 에러가 발생하니 검증하고자 하는 test method는 exception을 던질 거라고 assertion을 작성하면 된다.

    @Test
    void test() {
        // given
        Dto dto = generateDto();
        BDDMockito.willThrow(new RuntimeException("", new Exception()))
                  .given(myRepository).test(Mockito.any());

        // when
        Assertions.assertThatThrownBy(() -> sut.test(dto))
                  .isInstanceOf(RuntimeException.class);

        // then
        Mockito.verify(myRepository, Mockito.times(3)).test(Mockito.any());
    }
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.