Spock Spy / Mock не регистрирует вызовы - PullRequest
0 голосов
/ 30 марта 2020

В моем тестовом классе есть метод, который просто вызывает два других метода. Я пытаюсь написать тест, который проверяет, что эти два метода действительно вызваны, но никакие вызовы не зарегистрированы. 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 безрезультатно.

1 Ответ

1 голос
/ 30 марта 2020

Я пытался создать 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 в вашем классе, , что делает невозможным их издеваться, потому что mocks используют прокси-серверы Dynami c, а последние технически являются подклассами. Подклассы не видят частные методы суперкласса, поэтому, например, динамический c прокси не может перехватывать (вызывать) их.

Возможные решения:

  • Прекратите переопределять ваши тесты и тестируйте внутренние взаимодействия. Это делает тест хрупким, и вам придется часто проводить его рефакторинг, если вы также проводите рефакторинг тестируемого класса.

  • Сделайте методы populate* защищенными или пакетными, если publi c не правильно. Затем вы можете заглушить их и проверить взаимодействие с ними.

...