当前位置: 首页 > 知识库问答 >
问题:

Spock测试:调用太多

张鸿宝
2023-03-14
public class ReQueueService {
  private final RabbitTemplate rabbitTemplate;

  public void retry() {
    InfoLog infoLog;
    while (rabbitTemplate != null && 
      (infoLog = (InfoLog) rabbitTemplate.receiveAndConvert(EVENT_WAITING_FOR_REQUEUE)) != null
    ) {
      rabbitTemplate.convertAndSend(SOME_QUEUE, infoLog.getSomeEvent());
    }
  }
}
Too many invocations for:

1 * rabbitTemplate.convertAndSend(SOME_QUEUE, _ as SomeEvent) >> {
      arguments ->
        assert infoLog.getSomeEvent() == arguments[1]
    }   (2 invocations)

Matching invocations (ordered by last occurrence):

2 * rabbitTemplate.convertAndSend(SOME_QUEUE, ...
class ReQueueServiceTest extends Specification {
  def "should resend single event to some queue" () {
    given:
    InfoLog infoLog = Fixtures.createInfoLog()
    def rabbitTemplate = Mock(RabbitTemplate){
      receiveAndConvert(EVENT_WAITING_FOR_REQUEUE) >> { infoLog }
    }
    ReQueueService reSyncService = new ReQueueService(rabbitTemplate)

    when:
    reSyncService.retry()

    then:
    1 * rabbitTemplate.convertAndSend(SOME_QUEUE, _ as SomeEvent) >> {
      arguments ->
        assert infoLog.getSomeEvent() == arguments[1]
    }
  }
}

编辑:

链接到repo示例:https://gitlab.com/bartekwichowski/spock-too-many

共有1个答案

宋腾
2023-03-14

谢谢你的回购链接。一旦我能够运行测试并实时检查行为,就很容易发现哪里出了问题。首先,我将对您实际想要测试的内容进行一个有根据的猜测:

  1. 模拟的receiveandconvert方法在第一次调用时应该返回str,然后在再次调用时返回null
  2. 随后,您需要验证while循环是否恰好运行了1次迭代,即convertandsend是否使用了您所需的参数调用。

这可以通过以下方式实现

    null
class ReSyncServiceTest extends Specification {
  def "should resend single event to resource sync queue"() {
    given:
    def message = "someValue"
    def rabbitTemplate = Mock(RabbitTemplate) {
      receiveAndConvert("FOO") >>> [message, null]
    }

    when:
    new ReSyncService(rabbitTemplate).retry()

    then:
    1 * rabbitTemplate.convertAndSend("BAR", message)
  }
}
@Slf4j
@Service
@AllArgsConstructor
public class ReSyncService {
  private final RabbitTemplate rabbitTemplate;

  public void retry() {
    if (rabbitTemplate == null)
      return;
    String event;
    while (null != (event = getEventFromQueue()))
      rabbitTemplate.convertAndSend("BAR", event);
  }

  protected String getEventFromQueue() {
    return (String) rabbitTemplate.receiveAndConvert("FOO");
  }
}
 类似资料:
  • 下面是源代码和测试代码,有人能让我知道我做错了什么吗?似乎根本没有调用dao mock并返回“USA”。我在网上做了一些研究,找不到我做错了什么。 下面是我的Spock测试代码:

  • 注意:如果我不使用JMockit,我可以进行调试,但是在生产代码中测试方法需要使用这个方法。 关于如何让调试器从使用JMockit的Spock测试中停在Java代码中,有什么想法吗?

  • 我是Spock测试框架的新手,我试图为我正在工作的一个android项目做一些测试。我目前测试的这些对象是PJO,所以可以用常规的Spock测试它们。出于某种原因,我一直在我的一个对象上调用isAlive方法,但我知道它被调用了,感觉我已经在调试器中运行了它,它被调用了。所以我希望有人能引导我知道我做错了什么。 下面是我的测试代码: 任何帮助都将不胜感激。我已经在我能想到的每种配置中尝试过了...

  • 在我的应用程序中有,它有一个操作,如下所示: 现在,我正在测试视图和模型,如下所示: 但是我的测试用例失败了,stacktrace如下: 正在运行2个spock测试。。。第1页,共2页 有什么问题吗。

  • 我试图从Spock测试中扩展GebSpec的类调用java构造函数。我有这样一个错误:“不允许构造函数;相反,定义一个'setup()'或'setup spec()'方法”。我需要打这样的电话: