为什么我的测试无法在同一方法上进行两次交互?

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

我在 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>
java unit-testing testing groovy spock
1个回答
0
投票

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:
块中的交互进行匹配。由于该交互未指定响应,因此将返回方法返回类型的默认值(在本例中为
null
)。 (这只是 Spock 对嘲笑的宽容态度的另一个方面。)。因此,
given:
块中的交互永远不会有机会匹配。

注意: 同一方法调用的模拟和存根必须在同一交互中发生。

也就是说,你想使用类似的东西

1 * appointmentRepository.findById(nonExistingAppointmentId) >> {
  throw new AppointmentNotFoundException("Appointment with id " + nonExistingAppointmentId + " not found")
}

在您的

then:
区块中。

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