我的数据库有触发器。它们在创建实体后触发。我想测试一个条件,这取决于触发器执行的结果。所以,我需要能够在我的测试中看到这些结果。但触发器将在提交后触发,此时事务将实际回滚。
看来,我需要使用transactionTemplate
和PROPAGATION_REQUIRES_NEW
创建新的交易。我试过这种方式,我能够看到触发器执行的结果(horray!)。但这种方式会产生另一个问题:查看代码,我试图通过评论解释一个奇怪的行为。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class})
@Transactional
public class ServiceTest {
@Inject
private PlatformTransactionManager txManager;
<...>
@Before
public final void setUp() {
clearDatabase();
}
@Test
public final void testFilter() {
// Note: here database is empty - was cleared by setUp() method
TransactionTemplate tt = new TransactionTemplate(txManager);
tt.setPropagationBehavior(PROPAGATION_REQUIRES_NEW);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus s) {
createAndSaveEntity();
}
});
// Here I can see created entity and results of the trigger execution
// But also I see all entities, which was in the database before setUp()
// That is very strange! Why they appear if I deleted them?
<...>
}
}
PS:我使用的是Spring Data Neo4j 4.0.0.RELEASE和Neo4j 2.3.1
答案 0 :(得分:2)
Neo4j不支持嵌套事务。因此,如果事务事件处理程序(我假设您(正确地)称为“触发器”)丰富了事务,则它需要在beforeCommit()
中执行,并且它将参与全有或全无操作。测试的最佳选择是让事务提交,断言您需要断言的内容,并在每次测试之前或之后清除数据库。
(GraphAware RestTest可能有助于断言和清除,如果你真的是在远程数据库上运行。如果你使用嵌入式模式进行测试,请转到GraphUnit。)
你的问题实际上是不同的。看起来像某些东西(比如SDN Session
)在测试运行之间没有被清除。要么明确地清除它,要么使用@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
注释您的测试。