I am using spring boot and my integration test class is like following
@RunWith(SpringRunner.class)
@SpringBootTest(classes = IWantServiceRequestApp.class)
public class ServiceRequestResourceIntTest {
...
}
in the following test case i am updating "ServiceRequest" entity with address and passing invalid stateId
@Test
@Transactional
public void updateWithNonExistingState() throws Exception {
UpdateServiceRequestDTO updateServiceRequestDTO = serviceRequestMapper.toUpdateServiceRequestDTO(updatedServiceRequest);
updateWithDefaultUpdateValues(updateServiceRequestDTO); // update properties of updateServiceRequestDTO object
defaultUpdateAddressDTO.setStateId(NON_EXISTING_ID);
updateServiceRequestDTO.setServiceLocation(defaultUpdateAddressDTO);
String payload = TestUtil.convertObjectToJsonString(updateServiceRequestDTO);
restServiceRequestMockMvc.perform(put("/api/servicerequest")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(payload))
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.code").value(ResponseCodes.STATE_NOT_FOUND))
; // this calls ServiceRequestServiceImpl.update()
// Validate the ServiceRequest in the database
List<ServiceRequest> serviceRequests = serviceRequestRepository.findAll();
assertThat(serviceRequests).hasSize(databaseSizeBeforeUpdate);
ServiceRequest testServiceRequest = serviceRequests.get(serviceRequests.size() - 1);
assertNull(testServiceRequest.getServiceLocation());
assertThat(serviceRequest.getType()).isEqualTo(DEFAULT_TYPE); // **FAILS HERE**
}
when i run the above test case, it will throw Exception from service layer and @ControllerAdvice convert exception to proper rest response body. the problem however is that, in service layer the entity object will be updated with new field values from request, and then the exception is thrown, and when asserted DB for non updated field values, it gives updated values from DB.
@Service
@Transactional
public class ServiceRequestServiceImpl implements ServiceRequestService{
public ServiceRequestDTO update(UpdateServiceRequestDTO updateServiceRequestDTO) {
ServiceRequest serviceRequest = serviceRequestRepository.findOne(updateServiceRequestDTO.getId());
serviceRequestMapper.updateServiceRequest(updateServiceRequestDTO, serviceRequest);
// above method call will update fields object and then throw Exception, but the updated fields should not reflect in DB as the transaction will be rolled back due to exception
serviceRequest = serviceRequestRepository.save(serviceRequest);
ServiceRequestDTO result = serviceRequestMapper.toServiceRequestDTO(serviceRequest);
return result;
}
}
My thought is that, spring treats the @Transactional on @Test as the actual Transaction and does not rollback the Transaction declared on @Service, if that is the case then I would like to rollback the Service transaction only.
Aucun commentaire:
Enregistrer un commentaire