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:
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. Is there something obvious that I am doing wrong? Also tried using Mock instead of Spy to no avail.
I tried to create an MCVE from your sparse information and found no problems in your test:
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. 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. Then you can stub them and check interactions on them.