单元测试 ListenableFuture kafkaTemplate.send 总是 returns null
unit testing ListenableFuture kafkaTemplate.send always returns null
我正在尝试对来自 kafkaTemplate.send() 的回调进行单元测试,但它没有按预期工作。这是我正在尝试测试的代码片段。
@Override
public void sendMessage(String topicName, String message) {
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message);
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
@Override
public void onSuccess(SendResult<String, String> result) {
System.out.print("Success")
}
@Override
public void onFailure(Throwable ex) {
System.out.print("Failed")
}
});
}
这是单元测试代码
private KafkaTemplate<String, String> kafkaTemplate;
private KafkaService kafkaService;
private SendResult<String, String> sendResult;
private ListenableFuture<SendResult<String, String>> future;
private RecordMetadata recordMetadata
private String topicName
private String message
def setup() {
kafkaTemplate = Mock(KafkaTemplate.class)
kafkaService = new KafkaService(kafkaTemplate);
topicName = "test.topic"
message = "test message"
sendResult = Mock(SendResult.class);
future = Mock(ListenableFuture.class);
recordMetadata = new RecordMetadata(new TopicPartition(topicName, 1), 1L, 0L, 0L, 0L, 0, 0);
}
def "Test success send message method"() {
given:
sendResult.getRecordMetadata() >> recordMetadata
kafkaTemplate.send(_ as String, _ as String) >> future
when:
kafkaService.sendMessage(topicName, message)
then:
// catch success or failed here.
1 * kafkaTemplate.send(_,_) >> {arguments ->
final String topicNameParam = arguments.get(0)
final String messageParam = arguments.get(1)
assert topicNameParam == topicName
assert messageParam == message
}
}
基于调试器 future 在这种情况下为空
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message); // future null
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() { // future null
我已经在这里阅读了很多答案,但并没有解决问题,或者他们没有很好地解释我会明白问题出在哪里。像这个
提前感谢您的帮助!
因为你在嘲笑 KafkaTemplate
;您需要将发送方法模拟为 return 未来。
我对 Spock 不熟悉。
对于 Mockito,这将是
SettableListenerFuture<SendResult<?, ?>> future = new SettableListenerFuture<>();
given(template.send(anyString(), anyString())).willReturn(future);
您在尝试 combine mocking and stubbing 时犯了一个典型的 Spock 初学者错误:首先在 given:
块中声明一个存根结果,然后声明一个检查的模拟交互(without 存根结果)在 then:
块中。但是 mocking 和 stubbing 总是必须在同一个交互中发生 正如我链接到的手册章节中所描述的那样。该手册还解释说 then:
块中的交互在您的情况下获胜,即因为您没有在那里指定存根结果,结果将默认为 null
.
此外,您使论证验证变得比必要的困难得多。只需使用简单的参数约束即可。如果您这样更改它,您的测试将通过:
def "Test success send message method"() {
given:
sendResult.getRecordMetadata() >> recordMetadata
// kafkaTemplate.send(_ as String, _ as String) >> future
when:
kafkaService.sendMessage(topicName, message)
then:
// catch success or failed here.
1 * kafkaTemplate.send(topicName, message) >> future
}
我正在尝试对来自 kafkaTemplate.send() 的回调进行单元测试,但它没有按预期工作。这是我正在尝试测试的代码片段。
@Override
public void sendMessage(String topicName, String message) {
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message);
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
@Override
public void onSuccess(SendResult<String, String> result) {
System.out.print("Success")
}
@Override
public void onFailure(Throwable ex) {
System.out.print("Failed")
}
});
}
这是单元测试代码
private KafkaTemplate<String, String> kafkaTemplate;
private KafkaService kafkaService;
private SendResult<String, String> sendResult;
private ListenableFuture<SendResult<String, String>> future;
private RecordMetadata recordMetadata
private String topicName
private String message
def setup() {
kafkaTemplate = Mock(KafkaTemplate.class)
kafkaService = new KafkaService(kafkaTemplate);
topicName = "test.topic"
message = "test message"
sendResult = Mock(SendResult.class);
future = Mock(ListenableFuture.class);
recordMetadata = new RecordMetadata(new TopicPartition(topicName, 1), 1L, 0L, 0L, 0L, 0, 0);
}
def "Test success send message method"() {
given:
sendResult.getRecordMetadata() >> recordMetadata
kafkaTemplate.send(_ as String, _ as String) >> future
when:
kafkaService.sendMessage(topicName, message)
then:
// catch success or failed here.
1 * kafkaTemplate.send(_,_) >> {arguments ->
final String topicNameParam = arguments.get(0)
final String messageParam = arguments.get(1)
assert topicNameParam == topicName
assert messageParam == message
}
}
基于调试器 future 在这种情况下为空
ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message); // future null
future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() { // future null
我已经在这里阅读了很多答案,但并没有解决问题,或者他们没有很好地解释我会明白问题出在哪里。像这个
提前感谢您的帮助!
因为你在嘲笑 KafkaTemplate
;您需要将发送方法模拟为 return 未来。
我对 Spock 不熟悉。
对于 Mockito,这将是
SettableListenerFuture<SendResult<?, ?>> future = new SettableListenerFuture<>();
given(template.send(anyString(), anyString())).willReturn(future);
您在尝试 combine mocking and stubbing 时犯了一个典型的 Spock 初学者错误:首先在 given:
块中声明一个存根结果,然后声明一个检查的模拟交互(without 存根结果)在 then:
块中。但是 mocking 和 stubbing 总是必须在同一个交互中发生 正如我链接到的手册章节中所描述的那样。该手册还解释说 then:
块中的交互在您的情况下获胜,即因为您没有在那里指定存根结果,结果将默认为 null
.
此外,您使论证验证变得比必要的困难得多。只需使用简单的参数约束即可。如果您这样更改它,您的测试将通过:
def "Test success send message method"() {
given:
sendResult.getRecordMetadata() >> recordMetadata
// kafkaTemplate.send(_ as String, _ as String) >> future
when:
kafkaService.sendMessage(topicName, message)
then:
// catch success or failed here.
1 * kafkaTemplate.send(topicName, message) >> future
}