java - Spock Spy/Mock 未注册调用
问题描述
我的测试类中有一个方法,它只调用另外两个方法。我正在尝试编写一个测试来检查这两个方法是否实际被调用,但没有注册调用。我正在测试的 Java 代码:
public void populateEdgeInfo(Map<Actor, SchedulableNode> knownNodes) {
populateDestinationInfo(knownNodes);
populateSourceInfo(knownNodes);
}
我的测试代码:
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(_)
}
唯一注册的是对 populateEdgeInfo 的调用。有什么明显的我做错了吗?还尝试使用 Mock 而不是 Spy 无济于事。
解决方案
我试图从您的稀疏信息中创建一个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(_)
}
}
这意味着您的代码必须与我的不同。我的猜测是,这两种populate*
方法都private
在您的类中,这使得无法模拟它们,因为模拟使用动态代理,而后者在技术上是子类。但是,子类看不到私有超类方法,因此动态代理无法拦截(调用)它们。
可能的解决方案:
停止过度指定测试和测试内部交互。它使测试变得脆弱,如果您还重构被测类,则必须经常重构它。
populate*
如果 public 不正确,则将方法设为受保护或包范围。然后你可以存根它们并检查它们的交互。
推荐阅读
- angular - 在ngrx效果中获取json数据的问题
- iot - SIM5320E m2m sim卡
- laravel-livewire - 如何在 livewire 组件中进行 spatie/权限检查?
- javascript - 将 nuxt 3 从 TypeScript 迁移到 JavaScript
- excel - 使用 VBA 在 Excel 中查找与预定义特定模式不匹配的单元格
- excel - VB Excel Paste/Pastespecial 不粘贴公式,或者将一行粘贴为对象
- spring-tool-suite - STS(Spring Tool Suite)中的 Java EE 透视图
- javascript - 按返回未定义的索引记录数组项
- c++ - 如果一个字符串是一个char数组,你如何将它转换成一个整数数组
- python - 仅将 mp4 文件与 Pathlib 合并