unit testing ListenableFuture kafkaTemplate.send always returns null

我的未来我决定 提交于 2020-04-18 05:50:39

问题


I'm trying to unit test the callbacks from the kafkaTemplate.send() but its not working as expected. here's the code snippet of the code im trying to test.

    @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")
            }
        });
    }

and this is the unit test code


    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
        }
    }

based on the debugger future is null on this scenario

ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message); // future null
 future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() { // future null

i already read a lot of answers here but it does not solved the issue or havent they explain it well that i would understand where the problem is. like this one https://stackoverflow.com/a/56677098

thanks for the help in advance!


回答1:


You are making a typical Spock beginner's mistake when trying to combine mocking and stubbing: First declare a stub result in the given: block and later a checked mock interaction (without stub result) in the then: block. But mocking and stubbing always have to happen in the same interaction as described in the manual chapter I linked to. The manual also explains that the interaction in the then: block wins in your case, i.e. because you do not specify a stub result there, the result will default to null.

Furthermore, you make the argument verification much more difficult than necessary. Just use simple argument constraints instead. Your test will pass if you change it like this:

  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
  }



回答2:


Since you are mocking the KafkaTemplate; you need to mock the send method to return a future.

I am not familiar with Spock.

With Mockito, this would be

SettableListenerFuture<SendResult<?, ?>> future = new SettableListenerFuture<>();
given(template.send(anyString(), anyString())).willReturn(future);


来源:https://stackoverflow.com/questions/61100974/unit-testing-listenablefuture-kafkatemplate-send-always-returns-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!