模拟一个返回future以抛出异常的方法



我使用Java和Mockito模拟单元测试的一些方法。我想在下面的代码中模拟生产者,这样我就可以测试抛出异常时发送的日志消息。我试着嘲笑未来,但我得到的错误是future.get()方法不能被嘲笑,RecordMetadata类是最终的,不能被嘲笑。如有任何帮助,我将不胜感激。

下例中的生产者为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);
  }
}

Kafka提供了一个MockProducer类,你可以将它注入到你的类中进行测试。可以在JUnit @Before注释的设置方法中将类中的producer设置为MockProducer的实例。MockProducer的参考文档:

一个模拟的生产者接口,可以用来测试使用Kafka的代码。

默认情况下,此模拟将成功同步完成每个send调用。然而,它可以被配置为允许用户控制调用的完成,并为生产者提供一个可选的错误来抛出。

您可以使用#errorNext方法来提供您想要在测试场景中抛出的异常。

在没有看到测试代码的情况下很难做到精确。两个问题

1) RecordMetadata不能用于Mockito模拟,这是Mockito已知的限制。相反,您可以使用RecordMetadata的公共构造函数创建一个虚拟实例。

2) KafkaProducer可以被Mockito模拟,但是你需要一个两阶段的方法。首先,模拟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);
    }
}

相关内容

  • 没有找到相关文章

最新更新