如果@Test是@Transactional,@ SpringBootTest服务事务不回滚

时间:2016-10-19 07:40:07

标签: testing spring-boot transactions

我正在使用spring boot,我的集成测试类就像是

@RunWith(SpringRunner.class)
@SpringBootTest(classes = IWantServiceRequestApp.class)
public class ServiceRequestResourceIntTest {
 ...
}

在以下测试用例中,我正在使用地址更新“ServiceRequest”实体并传递无效的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**
}

当我运行上面的测试用例时,它会将异常从服务层和@ControllerAdvice转换异常抛出到正确的rest响应体。 然而问题是,在服务层中,实体对象将使用来自请求的新字段值进行更新,然后抛出异常,当为非更新字段值声明DB时,它会从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;
        }
    }

我的想法是,spring将@Test上的@Transactional视为实际的Transaction并且不回滚在@Service上声明的Transaction,如果是这种情况,那么我只想回滚Service事务。

0 个答案:

没有答案