You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单元测试Kafka发布者控制器时触发NullPointerException该如何解决

问题根因及修复方案

核心错误点

  • 未给Mock的KafkaTemplate的send方法打桩,Mock对象未配置返回值时默认返回null,后续调用.get()会直接触发空指针异常
  • 测试代码逻辑错位:postTo是控制器实例方法,不能直接用类名调用,也不应该在测试中手动调用kafkaTemplateMock.send
  • 未对publisherServicesMock的message方法打桩,无法匹配控制器中send方法的入参规则
  • 错误将kafkaTemplate.send的返回值当作控制器接口的返回结果进行校验

修正后的单元测试代码

def "published the topic"() {
  given:
  def kafkaTemplateMock  = Mock(KafkaTemplate.class)
  def publisherServicesMock = Mock(PublisherServices)
  def controller = new Controller(kafkaTemplateMock,publisherServicesMock)
  def model = new RequestModel(1234, "2345", "topic" )
  def mockMessage = "test-message" // 替换为实际message方法返回的同类型对象
  def mockFuture = Mock(ListenableFuture) // KafkaTemplate.send默认返回ListenableFuture类型

  // 打桩publisherServices的message方法,调用次数和循环次数一致
  1234 * publisherServicesMock.message(model) >> mockMessage
  // 打桩kafkaTemplate的send方法,返回mock的Future避免空指针
  1234 * kafkaTemplateMock.send("Kafka publisher", mockMessage) >> mockFuture
  // 打桩Future的get方法,模拟发送成功
  mockFuture.get() >> null

  when:
  def response = controller.postTo(model)

  then:
  response == "Published successfully to topic"
}

额外说明

  • 示例中RequestModel的count值为1234,对应循环执行1234次,因此两个Mock方法的调用次数配置为1234,如果count是动态参数可以用_匹配任意次数
  • 要模拟Kafka发送失败场景,只需让mockFuture.get()抛出对应的异常,即可验证异常处理逻辑

内容的提问来源于stack exchange,提问作者Medu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:15:02