我在 Spock/Groovy 测试方面遇到了困难。 不知道为什么,但在 WHEN 部分,我无法检查调用次数并立即检查值。 如果我单独检查其中之一,一切正常!
本次测试通过:
def "should throw AppointmentNotFoundException when appointment do not exist" () {
given:
long nonExistingAppointmentId = 69L
when:
appointmentRepository.findById(nonExistingAppointmentId) >> { throw new AppointmentNotFoundException("Appointment with id " + nonExistingAppointmentId + " not found") }
findAppointmentQueryHandler.handle(nonExistingAppointmentId)
then:
thrown(AppointmentNotFoundException)
}
这个也顺利通过了:
def "should throw AppointmentNotFoundException when appointment do not exist" () {
given:
long nonExistingAppointmentId = 69L
when:
appointmentRepository.findById(nonExistingAppointmentId) >> { throw new AppointmentNotFoundException("Appointment with id " + nonExistingAppointmentId + " not found") }
findAppointmentQueryHandler.handle(nonExistingAppointmentId)
then:
1 * appointmentRepository.findById(69L)
}
但是如果我尝试进行 1 个测试来检查所有内容,那么我就会出错
def "should throw AppointmentNotFoundException when appointment do not exist" () {
given:
long nonExistingAppointmentId = 69L
when:
appointmentRepository.findById(nonExistingAppointmentId) >> { throw new AppointmentNotFoundException("Appointment with id " + nonExistingAppointmentId + " not found") }
findAppointmentQueryHandler.handle(nonExistingAppointmentId)
then:
1 * appointmentRepository.findById(69L)
thrown(AppointmentNotFoundException)
}
错误:
Expected exception of type 'com.bbc.anotherhospital.exceptions.AppointmentNotFoundException', but no exception was thrown
at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:84)
at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:71)
at com.bbc.anotherhospital.appointment.handlers.FindAppointmentQueryHandlerSpec.should throw AppointmentNotFoundException when appointment do not exist
首先,我认为我的代码有问题。但是应用程序工作正常,在 Postman 中进行了测试。
有人知道为什么会这样吗?
我的pom:
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>4.0.15</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>2.4-M1-groovy-4.0</version>
<scope>test</scope>
</dependency>
Spock手册在章节“结合模拟和存根”中解释了为什么你所做的不起作用:
结合模拟和存根
模拟和存根是齐头并进的:
1 * subscriber.receive("message1") >> "ok" 1 * subscriber.receive("message2") >> "fail"
当模拟和存根同一方法调用时,它们必须在同一交互中发生。特别是,以下 Mockito 风格的将存根和模拟拆分为两个单独的语句将不会工作:
given: subscriber.receive("message1") >> "ok" when: publisher.send("message1") then: 1 * subscriber.receive("message1")
如在哪里声明交互中所述,
调用将首先与receive
块中的交互进行匹配。由于该交互未指定响应,因此将返回方法返回类型的默认值(在本例中为then:
)。 (这只是 Spock 对嘲笑的宽容态度的另一个方面。)。因此,null
块中的交互永远不会有机会匹配。given:
注意: 同一方法调用的模拟和存根必须在同一交互中发生。
也就是说,你想使用类似的东西
1 * appointmentRepository.findById(nonExistingAppointmentId) >> {
throw new AppointmentNotFoundException("Appointment with id " + nonExistingAppointmentId + " not found")
}
在您的
then:
区块中。