简体   繁体   English

Spock Spy/Mock 未注册调用

[英]Spock Spy/Mock not registering the invocations

I have a method in my test class that just calls two other methods.我的测试类中有一个方法,它只调用另外两个方法。 I am trying to write a test that checks that those two methods are actually invoced, but no invocations are registered.我正在尝试编写一个测试来检查这两个方法是否被实际调用,但没有调用被注册。 Java code I'm testing:我正在测试的 Java 代码:

    public void populateEdgeInfo(Map<Actor, SchedulableNode> knownNodes) {
        populateDestinationInfo(knownNodes);
        populateSourceInfo(knownNodes);
    }

My test code:我的测试代码:

def "Populating edge info means both source and destination information will be populated" () {
    given:
    actor.getDstChannels() >> []
    actor.getSrcChannels() >> []
    SchedulableNode schedulable = Spy(SchedulableNode, constructorArgs: [actor])

    when:
    schedulable.populateEdgeInfo([:])

    then:
    1 * schedulable.populateDestinationInfo(_)
    1 * schedulable.populateSourceInfo(_)
}

The only thing registered is the call to populateEdgeInfo.唯一注册的是对 populateEdgeInfo 的调用。 Is there something obvious that I am doing wrong?有什么明显的我做错了吗? Also tried using Mock instead of Spy to no avail.还尝试使用 Mock 而不是 Spy 无济于事。

I tried to create an MCVE from your sparse information and found no problems in your test:我尝试根据您的稀疏信息创建MCVE ,但在您的测试中没有发现任何问题:

package de.scrum_master.stackoverflow.q60926015;

import java.util.List;

public class Actor {
  public List getDstChannels() {
    return null;
  }

  public List getSrcChannels() {
    return null;
  }
}
package de.scrum_master.stackoverflow.q60926015;

import java.util.Map;

public class SchedulableNode {
  private Actor actor;

  public SchedulableNode(Actor actor) {
    this.actor = actor;
  }

  public void populateEdgeInfo(Map<Actor, SchedulableNode> knownNodes) {
    populateDestinationInfo(knownNodes);
    populateSourceInfo(knownNodes);
  }

  public void populateDestinationInfo(Map<Actor, SchedulableNode> knownNodes) {}

  public void populateSourceInfo(Map<Actor, SchedulableNode> knownNodes) {}
}
package de.scrum_master.stackoverflow.q60926015

import spock.lang.Specification

class SchedulableNodeTest extends Specification {
  def actor = Mock(Actor)

  def "Populating edge info means both source and destination information will be populated"() {
    given:
    actor.getDstChannels() >> []
    actor.getSrcChannels() >> []
    SchedulableNode schedulable = Spy(SchedulableNode, constructorArgs: [actor])

    when:
    schedulable.populateEdgeInfo([:])

    then:
    1 * schedulable.populateDestinationInfo(_)
    1 * schedulable.populateSourceInfo(_)
  }
}

That means that your code must be different from mine.这意味着您的代码必须与我的不同。 My guess is that both populate* methods are private in your class, which makes it impossible to mock them because mocks use dynamic proxies and the latter are sub-classes technically.我的猜测是populate*方法在您的类中都是private这使得无法模拟它们,因为模拟使用动态代理,而后者在技术上是子类。 Sub-classes do not see private super-class methods, though, thus a dynamic proxy cannot intercept (calls to) them.但是,子类看不到私有的超类方法,因此动态代理无法拦截(调用)它们。

Possible solutions:可能的解决方案:

  • Stop over-specifying your tests and testing internal interactions.停止过度指定您的测试和测试内部交互。 It makes the test brittle and you have to refactor it often if you also refactor the class under test.它使测试变得脆弱,如果您还重构被测类,则必须经常重构它。

  • Make the populate* methods protected or package-scoped if public is not right.如果 public 不正确,则将populate*方法设为 protected 或 package-scoped。 Then you can stub them and check interactions on them.然后你可以存根它们并检查它们的交互。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM