Spock测试因MissingPropertyException而失败

问题描述 投票:1回答:2

我有一个简单的类,它基于简单的规则构建RequestMessage

  • 如果在数据库中找到MessageMetadata,则使用该元数据构建消息。
  • 否则,将使用提供元数据的服务来构建消息。

这里是班级和Spock测试。测试失败,并显示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
}

我真的很想了解为什么这不起作用。感谢您在成功测试此测试方面的帮助。谢谢

java unit-testing spock
2个回答
0
投票

问题的确是我在对[[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

,然后将其用作存根结果将不会单独完成。您需要确保首先声明一个将由builder方法返回的对象(例如,模拟对象),然后将被测方法调用的结果分配给另一个变量,以便您可以比较两者或执行所需的任何验证执行: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
投票
尝试在requestMessage块而不是given块中声明when

Spock lifecycle具有一些令人惊讶的行为,其中之一是interactions块的[[before被处理。

© www.soinside.com 2019 - 2024. All rights reserved.