Тест Спока не работает с MissingPropertyException - PullRequest
1 голос
/ 10 февраля 2020

У меня есть простой класс, который строит RequestMessage на основе простого правила.

  • Если в базе данных найдено MessageMetadata, сообщение создается с использованием этих метаданных.
  • В противном случае сообщение создается с использованием службы, предоставляющей метаданные.

Здесь представлен класс вместе с тестом Спока. Тест не пройден с MissingPropertyException, говоря, что он не может найти RequestMessage, созданный с помощью сервиса.

class MessageService{
    MessageBuilder messageBuilder;
    MessageRepository messageRepository;
    MessageMetadaProvider messageMetaDataProvider;

    public RequestMessage getMessage(String id ) {
        try {
            MessageMetadata metadata = repository.findDefaulMessage(id);
            RequestMessage requestMessage = builder.createMessage(metadata);
            return requestMessage;
        } catch (DataNotFoundException e) {
            e.printStackTrace();
        }
        MessageMetadata metadata = messageMetaDataProvider.createNewMessageMetadata(id);
        RequestMessage message = messageBuilder.buildNew(id , metadata);
        return message;
    }
}

def "Build Request Message  "() {
    given:
    String id = '12345'
    MessageBuilder messageBuilder = Mock()
    MessageRepository messageRepository = Mock()
    MessageMetadaProvider messageMetaDataProvider = Mock()
    MessageService service = createMessageService(messageRepository,messageBuilder,messageMetaDataProvider)
    MessageMetadata metadata = new MessageMedata(id, MessageType.DEFAULT)
    when:
    RequestMessage requestMessage = messageService .getMessage(id )
    then:
    1 * messageRepository.repository.findDefaulMessage(id) >> {throw new DataNotFoundException("Not Found")}
    1 * messageMetaDataProvider.createNewMessageMetadata(id) >> metadata
    1  *  messageBuilder.buildNew(id , metadata) >> requestMessage
}

Я действительно хотел бы понять, почему это не работает Я благодарен за любую помощь в успешном тестировании этого теста. Спасибо

Ответы [ 2 ]

0 голосов
/ 10 февраля 2020

Проблема действительно в проблеме курицы и яйца, о которой я упоминал в своем комментарии к jaco0646 ответу. Позвольте мне воссоздать основную проблему в MCVE :

package de.scrum_master.stackoverflow.q60143388;

public class RequestMessage {}
package de.scrum_master.stackoverflow.q60143388;

public class MessageService {
  MessageBuilder messageBuilder;

  public RequestMessage getMessage(String id) {
    return messageBuilder.buildNew(id);
  }
}
package de.scrum_master.stackoverflow.q60143388

import spock.lang.Specification

class MessageServiceTest extends Specification {
  def "build request message"() {
    given:
    def id = "12345"
    MessageBuilder messageBuilder = Mock()
    MessageService messageService = new MessageService()
    messageService.messageBuilder = messageBuilder

    when:
    RequestMessage requestMessage = messageService.getMessage(id)

    then:
    1 * messageBuilder.buildNew(id) >> requestMessage
  }
}

Это даст:

groovy.lang.MissingPropertyException: No such property: requestMessage for class: de.scrum_master.stackoverflow.q60143388.MessageServiceTest

    at de.scrum_master.stackoverflow.q60143388.MessageServiceTest.build request message(MessageServiceTest.groovy:17)

Просто объявив requestMessage в блок given:, как предложено jaco0646 , и затем использование его в качестве результата-заглушки не сделает это в одиночку. Вы должны убедиться, что сначала объявляете объект (например, макет), который должен быть возвращен методом построителя, но присваиваете результат тестируемого вызова метода другой переменной, чтобы вы могли сравнить их или сделать любую проверку, какую захотите выполните:

package de.scrum_master.stackoverflow.q60143388

import spock.lang.Specification

class MessageServiceTest extends Specification {
  def "build request message"() {
    given:
    def id = "12345"
    RequestMessage requestMessage = Mock()
    MessageBuilder messageBuilder = Mock()
    MessageService messageService = new MessageService()
    messageService.messageBuilder = messageBuilder

    when:
    RequestMessage result = messageService.getMessage(id)

    then:
    1 * messageBuilder.buildNew(id) >> requestMessage
    result.toString().startsWith("Mock for type 'RequestMessage'")
  }
}

Теперь тест пройден, и ваша проблема с загрузкой решена. Вы не можете создать объект с помощью вызова метода, а затем одновременно указать его как ожидаемый результат заглушки. Это не имеет никакого логического смысла.

0 голосов
/ 10 февраля 2020

Попробуйте объявить requestMessage в блоке given, а не в блоке when.

Spock lifecycle имеет некоторые неожиданные поведения, одним из которых является то, что взаимодействия обрабатываются до блока when.

...