2016-10-04 4 views
2

나는 단위 테스트를위한 몇 가지 방법을 조롱하기 위해 Java와 Mockito를 사용하고 있습니다. 예외가 발생했을 때 전송되는 로그 메시지를 테스트 할 수 있도록 아래 코드에서 제작자를 조롱하고 싶습니다. 미래를 조롱했지만 future.get() 메서드를 조롱 할 수없고 RecordMetadata 클래스가 final이며 조롱을받을 수 없다는 오류가 발생했습니다. 어떤 도움이라도 대단히 감사하겠습니다.예외를 던지 미래를 돌려주는 메소드 모의

아래 예제의 제작자는 KafkaProducer입니다.

public void send(Log log){ 
    Future<RecordMetadata> future = producer.send(new ProducerRecord<(this.topic, record)); 
    try { 
    RecordMetadata recordMetadata = send.get(); 
    } catch (InterruptedException e) { 
    LOG.error("Sending the message to kafka was interrupted. "+e); 
    } 
} 

답변

3

카프카는 시험용으로 반입 할 수있는 MockProducer 클래스를 제공합니다. JUnit @Before -annotated 설정 방법으로 클래스의 producerMockProducer의 인스턴스로 설정할 수 있습니다. MockProducer에 대한 참조 문서에서 :

카프카를 사용하는 코드를 테스트하는 데 사용할 수있는 생산자 인터페이스 모의.

기본적으로이 모의 작업은 각 전송 호출을 동기화하여 완료합니다. 그러나 사용자가 호출 완료를 제어하고 제작자가 던져야 할 선택적 오류를 제공 할 수 있도록 구성 할 수 있습니다.

#errorNext 메서드를 사용하여 테스트 시나리오에서 예외를 제공 할 수 있습니다.

+0

감사합니다. errorNext가 send 메소드가 throw 할 수있는 두 가지 유형의 예외 (InterruptedException) 중 하나를 throw 할 수 없다는 사실을 조금 바보스럽게 생각합니다. – annedroiid

+0

RuntimeException 유형의 예외를 지정할 수 있습니다. 이는 InterruptedException이 확장되는 것입니다 –

1

테스트 코드를 보지 않고도 여기에서 정확하기는 어렵습니다. 두 가지 문제

1) RecordMetadata는 모의도 모의 (mockito mock)로 사용할 수 없습니다. 이것은 모키토의 알려진 제한 사항입니다. 대신 public 생성자를 사용하여 RecordMetadata의 더미 인스턴스를 만들 수 있습니다.

2) KockkaProducer는 Mockito가 조롱 할 수 있지만 2 단계 접근이 필요합니다. 먼저 모의 KafkaProducer가 Future를 반환하고, 둘째 Future도 모호한 값을 반환하는 모의 객체입니다.

public class ServiceTest { 

    @Mock 
    private KafkaProducer<String, Integer> producer; 
    @Mock 
    private Future<RecordMetadata> future; 

    @Before 
    public void setup() { 
     MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    public void success() throws Exception { 
     RecordMetadata dummyRecord = new RecordMetadata(null, 0L, 0L, 0L, 0L, 0, 0); 
     when(producer.send(any())).thenReturn(future); 
     when(future.get()).thenReturn(dummyRecord); 

     producer.send(null); 
    } 

    @Test 
    public void timeout() throws Exception { 
     when(producer.send(any())).thenReturn(future); 
     when(future.get()).thenThrow(new TimeoutException("timeout")); 

     producer.send(null); 
    } 
} 
관련 문제