2017-10-26 1 views
0

작업이 거의 실패 할 수 없기 때문에 간단한 재 시도를합니다. 간단한 코드는 다음과 같습니다. putObject 메서드는 우연히 예외를 throw 할 수 있습니다.이 경우 재 시도가이 메서드를 다시 호출 할 수 있어야합니다. JUnit 테스트를 작성할 수 있습니까? Mockito 라이브러리를 사용하면 메서드를 호출하는 Exception을 throw 할 수는 있지만이 예외를 강제로 한 번만 throw하는 방법은 알고 있습니다.JUNIT/Mockito 테스트를 다시 시도 할 때 예외를 한 번만 던지는 것을 시뮬레이트하는 방법은 무엇입니까?

public class RetryExample { 
Bucket bucket = new Bucket(); 
static int INTERNAL_EXCEPTION_CODE = 100; 
class AException extends RuntimeException { 
    private static final long serialVersionUID = 1L; 
    int statusCode; 
    public int getStatusCode() { 
     return statusCode; 
    } 
} 

class Bucket { 
    public void putObject(String fileName, byte[] data) throws AException { 
     System.out.println("PutObject=" + fileName + " data=" + data); 
    } 
} 

public void process(String fileName, byte[] data) throws AException { 
    try { 
     retryOperation((f, d) -> bucket.putObject(f, d), fileName, data); 
    } catch (Exception ex) { 
     throw new AException("Failed to write data", ex); 
    } 
} 

private <T, U> void retryOperation(BiConsumer<T, U> biConsumer, T t, U u) { 
    int retries = 0; 
    boolean retry = false; 
    AException lastServiceException = null; 
    do { 
     try { 
      biConsumer.accept(t, u); 
     } catch (AException e) { 
      lastServiceException = e; 
      int statusCode = e.getStatusCode(); 
      if (statusCode == INTERNAL_EXCEPTION_CODE) { 
       throw e; 
      } else { 
       break; 
      } 
     } 
     retries++; 
     if (retries >= 3) { 
      retry = false; 
     } 
    } while (retry); 
    if (lastServiceException != null) { 
     throw lastServiceException; 
    } 
} 

테스트 클래스 :

public class RetryExampleTest { 
... 
@Test 
public void test() { 
    RetryExample retryExample = new RetryExample(); 
    String fileName = "TestFile"; 
    byte[] data = simulatedPayload(10000); 
    try { 
     retryExample.process(fileName, data); 
    } catch (Exception e) { 
     fail("Exception thrown=" + e); 
    } 
} 

답변

1

Mockito documentation에 따르면 연속적인 메서드 호출에 대해 다른 동작을 설정할 수 있습니다. 당신이 비슷한 (Mockito documentation)

doThrow(new RuntimeException()) 
    .doNothing() 
    .when(mock).doSomething(); 
+0

우수함 할 수있는 공간 방법의 경우

when(mock.someMethod("some arg")) .thenThrow(new RuntimeException()) .thenReturn("foo"); 

! mock.someMethod가 무효라면? –

+0

그것은 .when (모의) .doSomething() 무효 메소드입니까? (모의은 괄호 안의) –

+0

그리고 doReturn ("foo") 대신 doNothing입니까? –

0

나는 당신이 단지에 글로벌 데이터 객체를 촬영 Mockito 라이브러리에 예외 메소드를 호출하므로, 던져 예외의 시간을 저장하기 위해 글로벌 데이터 개체를 사용할 수 있다고 생각 시간을 기록하십시오. 그것은 간단합니다. 그냥 모든 것을 제어 할 수 있습니다.

관련 문제