Prz*_*Etz 5 java groovy unit-testing spock spring-data-jpa
我正在使用 Spock 对我的应用程序中的服务进行单元测试。最近我遇到了一个我不太理解的奇怪行为。
这是我的单元测试:
def setup() {
parkingSessionRepository = Mock(ParkingSessionRepository.class)
parkingSessionMapper = Stub(ParkingSessionMapper.class)
parkingMeterService = new ParkingMeterService(parkingSessionRepository, parkingSessionMapper)
}
def "should start parking session for vehicle that doesn't have an active parking session"() {
given:
String testVehicleId = "AWC1342"
long testParkingRateId = 1
ParkingStartDTO testParkingStartDTO = ParkingStartDTO.builder()
.vehicleId(testVehicleId)
.parkingRateId(testParkingRateId)
.build()
ParkingSession testParkingSession = ParkingSession.builder()
.vehicleId(testVehicleId)
.parkingRate(ParkingRate.REGULAR)
.build()
parkingSessionMapper.fromParkingStartDTO(_) >> testParkingSession
parkingSessionRepository.save(_ as ParkingSession) >> testParkingSession
parkingSessionRepository.findByVehicleIdAndStopTimeIsNull(_ as String) >> Optional.empty()
when:
ParkingMeterResponseDTO parkingMeterResponseDTO = parkingMeterService.startParkingMeter(testParkingStartDTO)
then:
1 * parkingSessionRepository.save(_ as ParkingSession)
parkingMeterResponseDTO.vehicleId == testVehicleId
Assert.assertNotNull(parkingMeterResponseDTO.parkingSessionId)
Assert.assertNotNull(parkingMeterResponseDTO.timestamp)
}
Run Code Online (Sandbox Code Playgroud)
而测试服务方法的代码是:
public ParkingMeterResponseDTO startParkingMeter(final ParkingStartDTO parkingStartDTO) {
String vehicleId = parkingStartDTO.getVehicleId();
if (isParkingSessionAlreadyActive(vehicleId)) {
throw new ParkingSessionAlreadyActiveException();
} else {
ParkingSession parkingSession = parkingSessionMapper.fromParkingStartDTO(parkingStartDTO);
parkingSession.setStartTime(Timestamp.from(Instant.now()));
parkingSession = parkingSessionRepository.save(parkingSession);
return ParkingMeterResponseDTO.builder()
.vehicleId(parkingSession.getVehicleId())
.parkingSessionId(parkingSession.getId())
.timestamp(parkingSession.getStartTime())
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我运行单元测试时,会出现来自“when”块的 NullPointerException 结果(save() 方法返回 null)。但是,当我从“then”块中删除 save() 方法检查时 - 一切正常,没有空值。
这种行为的原因可能是什么?我怀疑存储库存在一些模拟问题,但我不确定幕后究竟发生了什么以及如何解决问题,以便 save() 方法检查“then”块按预期工作?
小智 7
请查看 Spock 文档: http://spockframework.org/spock/docs/1.0/interaction_based_testing.html
部分:结合模拟和存根
结合:
given:
...
parkingSessionRepository.save(_ as ParkingSession) >> testParkingSession
...
then:
1 * parkingSessionRepository.save(_ as ParkingSession)
Run Code Online (Sandbox Code Playgroud)
不管用。您必须使用一种表达方式:
1 * parkingSessionRepository.save(_ as ParkingSession) >> testParkingSession
Run Code Online (Sandbox Code Playgroud)