Java 模拟返回未来以引发异常的方法
我正在使用Java和Mockito来模拟一些用于单元测试的方法。我想在下面的代码中模拟生产者,以便在抛出异常时测试发送的日志消息。我尝试模拟future,但是我得到一个错误,即future.get()方法不能模拟,并且Java 模拟返回未来以引发异常的方法,java,mockito,Java,Mockito,我正在使用Java和Mockito来模拟一些用于单元测试的方法。我想在下面的代码中模拟生产者,以便在抛出异常时测试发送的日志消息。我尝试模拟future,但是我得到一个错误,即future.get()方法不能模拟,并且RecordMetadata类是最终类,不能模拟。任何帮助都将不胜感激 下面示例中的制作人是一个KafkaProducer public void send(Log log){ Future<RecordMetadata> future = producer.sen
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);
}
}
公共作废发送(日志){
Future Future=producer.send(new ProducerRecordKafka提供了一个类,您可以将该类中的producer
设置为JUnit@Before
-注释设置方法中的MockProducer
的实例。从MockProducer
的参考文档中:
可用于测试使用Kafka的代码的生产者界面的模拟。
默认情况下,此模拟将成功同步完成每个发送调用。但是,可以将其配置为允许用户控制调用的完成,并提供可选错误供生产者抛出
您可以使用该方法提供要在测试场景中抛出的异常。如果不查看您的测试代码,则很难在此处精确说明。有两个问题
1) RecordMetadata不能用于Mockito mock,这是Mockito的已知限制。相反,您可以使用其公共构造函数创建RecordMetadata的虚拟实例
2) KafkaProducer可以被Mockito模仿,但是你需要一个两阶段的方法。首先,模仿KafkaProducer返回一个未来,其次,这个未来也是一个返回一些已知值的模仿
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);
}
}
公共类服务测试{
@嘲弄
私人卡夫卡制作人;
@嘲弄
私人未来;
@以前
公共作废设置(){
initMocks(this);
}
@试验
public void success()引发异常{
RecordMetadata dummyRecord=新的RecordMetadata(null,0L,0L,0L,0L,0,0);
when(producer.send(any())。然后return(future);
when(future.get()).thenReturn(dummyRecord);
producer.send(空);
}
@试验
public void timeout()引发异常{
when(producer.send(any())。然后return(future);
when(future.get()).thenthow(newtimeoutexception(“timeout”));
producer.send(空);
}
}
谢谢,效果很好。尽管我觉得errorNext不能抛出两种类型的异常之一(InterruptedException)有点傻它允许您指定RuntimeException类型的异常,这就是InterruptedExceptionextends@GaryO'Donoghue InterruptedException扩展异常而非RuntimeException