[英]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.