我已经通过q& a围绕这个问题做了一些研究。很多问题似乎都在解决,但不是真的。
所以这就是事情:
我收到CaseController
,代理CaseService
,代理人转而CaseRepository
。
我在@Transactional
CaseServiceImpl
了
我收到CaseControllerIntegrationTest
,我从CaseController
执行RESTful请求并测试完整周期。
问题是 - 我的交易没有回滚。
其中一项测试是
@Test
public void verifyDeleteSuccessfulOnExistingCase() {
final String urlWithPlaceholders = serverPrefix + RequestMappings.CASES_RESOURCE_MAPPING + "/{caseId}";
final ResponseEntity<CaseResource> response =
restTemplate.exchange(
urlWithPlaceholders,
HttpMethod.DELETE,
null,
CaseResource.class, existingWsId_1, caseId);
assertThat(response, notNullValue());
assertThat(response.getBody(), nullValue());
assertThat(response.getStatusCode(), is(HttpStatus.NO_CONTENT));
assertThat(caseRepository.exists(caseId), is(false));
}
在这个测试中,我删除了一个在启动时为我插入的案例,感谢hibernate和import.sql
测试成功,问题是我想在接下来的测试中继续解决这种情况,但事务似乎没有回滚,并且案例被永久删除,不能用于下一次测试。
我尝试将@Transactional
从CaseServiceImpl
移到CaseController
,但它没有任何区别。
我可以说我的下方杆CaseRepositoryTest
在每次测试后都成功执行了回滚。
在CaseControllerIntegrationTest
之上我得到了:
@ActiveProfiles("integration-test")
@Transactional
@TransactionConfiguration
@IntegrationTest
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = AppConfiguration.class)
public class CaseControllerIntegrationTest {
...
AppConfiguration
看起来像这样:
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableTransactionManagement
public class AppConfiguration {
}
我正在使用的数据库是 hsqldb
最后一条重要信息 - 日志实际上表明回滚已完成:
2014-05-15 07:54:44.391 TRACE - o.s.t.c.t.TransactionalTestExecutionListener - 结束交易 测试上下文[DefaultTestContext @ 2eb0cefe testClass = CaseControllerIntegrationTest,testInstance = om.services.casemanagement.web.CaseControllerIntegrationTest@5a2ae1ab, testMethod = verifyDeleteSuccessfulOnExistingCase @CaseControllerIntegrationTest, testException = [null],mergedContextConfiguration = [WebMergedContextConfiguration @ 2bec068b testClass = CaseControllerIntegrationTest,locations ='{}',classes ='{class om.services.AppConfiguration}',contextInitializerClasses ='[]', activeProfiles ='{integration-test}',resourceBasePath = 'src / main / webapp',contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader',父 = [null]]];交易状态[org.springframework.transaction.support.DefaultTransactionStatus@3869a6e5]; rollback [true]
2014-05-15 07:54:44.403 INFO - o.s.t.c.t.TransactionalTestExecutionListener - 回滚事务 测试执行测试上下文后[DefaultTestContext @ 2eb0cefe testClass = CaseControllerIntegrationTest,testInstance = om.services.casemanagement.web.CaseControllerIntegrationTest@5a2ae1ab, testMethod = verifyDeleteSuccessfulOnExistingCase @CaseControllerIntegrationTest, testException = [null],mergedContextConfiguration = [WebMergedContextConfiguration @ 2bec068b testClass = CaseControllerIntegrationTest,locations ='{}',classes ='{class om.services.AppConfiguration}',contextInitializerClasses ='[]', activeProfiles ='{integration-test}',resourceBasePath = 'src / main / webapp',contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader',父 = [null]]]
我正在使用Spring 4.0.3发行版。
有什么想法吗?
答案 0 :(得分:2)
看看你在这里做了什么:
您从 thread1 发送http请求,该请求由Web容器的 thread2 捕获并处理。前者无法控制后者管理的交易。
如果您持有CaseController
实例并直接从测试方法对其方法进行显式调用,您将享受@Transactional
为您提供的自动回滚功能。
答案 1 :(得分:2)
尽管@kumetix提到了它,但对此的正确答案是,无法在测试方法中回滚通过RestTemplate发出的请求触发的事务
您唯一的选择是通过手动删除来回滚交易。
请参阅此link with similiar question以获取其他意见。
希望有所帮助。
答案 2 :(得分:0)
这种方式适合我。
private MockMvc restCaseController;
@Autowired
private CaseService caseService;
@Before
private void setup() {
MockitoAnnotations.initMocks(this);
CaseController casecontroller = new CaseController(caseService);
this.restCaseController =
MockMvcBuilders.standaloneSetup(casecontroller).build();
}
@Test
@Transactional
public void testMethod() {
restCaseController.perform(post("/api/post")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(jsonObject))
.andExpect(status().isCreated());
}
这种方式对我有用,我能够在没有任何回滚问题的情况下得到响应。