【问题标题】:MissingPropertyException in Spock testSpock 测试中的 MissingPropertyException
【发布时间】:2021-12-29 13:02:44
【问题描述】:

我对用 groovy 编写的测试有疑问(使用 Spock 作为框架)。当我尝试在then 块中获取属性然后在交互中使用它时,我在与事件发布者的交互中收到No such property: updatedValue for class: my.test.class.MyTestClass。谁能告诉我这是为什么?

class MyTestClass extends Specification {


@Autowired
private MyClass sut

@Autowired
private MyClassRepository myClassRepository


@SpringBean
private EventPublisher eventPublisher = Mock()


def "Should do something"() {
    given:
    //some data
    def someId = "someId"
    def event = new SomeEventObject()

    when:
    sut.handle(event)

    then:
    def updatedValue = myClassRepository.findTestClass(someId)
    updatedTestClass.cash == 100

    1 * eventPublisher.publishEvent(new SomeNextEvent(updatedValue))
}
}

【问题讨论】:

    标签: java spring-boot spock


    【解决方案1】:

    你遇到了 Spock 魔法的副作用。

    你的方法基本上变成了这样:

    public void $spock_feature_0_0() {
            org.spockframework.runtime.ErrorCollector $spock_errorCollector = org.spockframework.runtime.ErrorRethrower.INSTANCE
            org.spockframework.runtime.ValueRecorder $spock_valueRecorder = new org.spockframework.runtime.ValueRecorder()
            java.lang.Object someId = 'someId'
            java.lang.Object event = new apackage.SomeEventObject()
            this.getSpecificationContext().getMockController().enterScope()
            this.getSpecificationContext().getMockController().addInteraction(new org.spockframework.mock.runtime.InteractionBuilder(25, 9, '1 * eventPublisher.publishEvent(new SomeNextEvent(updatedValue))').setFixedCount(1).addEqualTarget(eventPublisher).addEqualMethodName('publishEvent').setArgListKind(true, false).addEqualArg(new apackage.SomeNextEvent(updatedValue)).build())
            sut.handle(event)
            this.getSpecificationContext().getMockController().leaveScope()
            java.lang.Object updatedValue = myClassRepository.findTestClass(someId)
            try {
                org.spockframework.runtime.SpockRuntime.verifyCondition($spock_errorCollector, $spock_valueRecorder.reset(), 'updatedTestClass.cash == 100', 23, 13, null, $spock_valueRecorder.record($spock_valueRecorder.startRecordingValue(3), $spock_valueRecorder.record($spock_valueRecorder.startRecordingValue(1), $spock_valueRecorder.record($spock_valueRecorder.startRecordingValue(0), updatedTestClass).cash) == $spock_valueRecorder.record($spock_valueRecorder.startRecordingValue(2), 100)))
            }
            catch (java.lang.Throwable throwable) {
                org.spockframework.runtime.SpockRuntime.conditionFailedWithException($spock_errorCollector, $spock_valueRecorder, 'updatedTestClass.cash == 100', 23, 13, null, throwable)}
            finally {
            }
            this.getSpecificationContext().getMockController().leaveScope()
        }
    

    如果您仔细观察,您会发现交互定义被移动到之前 when 块,但findTestClass() 调用留在后面。 这就是为什么您会收到缺少属性异常的原因。

    解决方案是将查找移动到 given 块,或者如果不可能,则使用参数捕获,然后再检查。

    given:
    def capturedEvent
    
    when:
    ...
    
    then:
    1 * eventPublisher.publishEvent(_) >> { capturedEvent = it[0} }
    
    and:
    
    def updatedValue = myClassRepository.findTestClass(someId)
    capturedEvent instanceof SomeNextEvent
    capturedEvent.value == updatedValue 
    

    您可以点击Inspect AST,在groovy web console 中自己查看转换后的代码。

    【讨论】:

    • 因为第一次想玩GWC,想知道在里面编辑代码是多么的容易或繁琐,我手动让Leonard的例子通过添加一些方法成功运行测试,初始化一些对象并修复小错误,例如正确拼写instanceof。更新后的代码是here
    猜你喜欢
    • 2015-10-07
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    相关资源
    最近更新 更多