Neo4j GraphUnit-事务集成测试和回滚
我目前正在使用GraphUnit、Spock和进程中的Neo4j服务器对我的Spring Data Neo4j 4.0支持的应用程序进行集成测试 在我的测试操作之后,它是一个非常好的工具,用于对图形数据库的状态进行断言,但我注意到,为了让GraphUnit的Neo4j GraphUnit-事务集成测试和回滚,neo4j,spring-data-neo4j-4,graphaware,Neo4j,Spring Data Neo4j 4,Graphaware,我目前正在使用GraphUnit、Spock和进程中的Neo4j服务器对我的Spring Data Neo4j 4.0支持的应用程序进行集成测试 在我的测试操作之后,它是一个非常好的工具,用于对图形数据库的状态进行断言,但我注意到,为了让GraphUnit的assertGraph和printGraph显示我的期望,必须首先提交我的Neo4j事务。从逻辑上讲,这对我来说是有意义的,但也意味着我不能标记我的集成测试@Transactional,并且在一个测试中对进程内数据库所做的任何数据更改都将流入
assertGraph
和printGraph
显示我的期望,必须首先提交我的Neo4j事务。从逻辑上讲,这对我来说是有意义的,但也意味着我不能标记我的集成测试@Transactional
,并且在一个测试中对进程内数据库所做的任何数据更改都将流入后续测试
我通过在Spock fixture方法中的每个测试方法之后清除数据库来处理此问题,这很好,但我非常希望能够:
- 设置一次测试Neo4j数据集
- 在每次试验后,对试验方法进行更改
- 仍然能够使用GraphUnit的断言和打印实用程序
我的问题是——有没有办法做到这三点?如果我想使用GraphUnit,事务提交是否是一个基本要求/假设?虽然您可以轻松地管理测试方法之间的Neo4j事务,但这里的棘手问题是让GraphUnit使用您的测试方法参与的同一事务进行断言 考虑到GraphUnit需要您使用
GraphDatabaseService
,恐怕您最好的选择就是为每个测试重新创建测试数据
尽管如此,通过为此使用可重用的JUnit测试规则,您可能会节省一些工作,因为它减轻了为每个测试工具编写分解方法的需要。在实现org.junit.rules.TestRule
的类中,可以在其构造函数中设置GraphDatabaseService
,然后执行以下操作:
@Override
public Statement apply(final Statement baseStatement, Description description) {
setUpTestData();
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
if (graphDatabaseService.isAvailable(1000)) {
baseStatement.evaluate();
} else {
Assert.fail("Database was shut down or didn't become available within 1s");
}
} finally {
resetDatabase();
}
}
};
}
public void setUpTestData() {
// can set up common test data here, or just use an @Before method in the test harness
}
public void resetDatabase() {
this.graphDatabaseService.execute("MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE r, n");
}
public class ArbitraryTest {
@Rule
public final Neo4jTestRule neo4jRule = new Neo4jTestRule();
@Test
public void arbitraryTestMethod() {
// some code...
GraphUnit.assertSameGraph(sameGraphCypher, neo4jRule.getGraphDatabaseService());
}
}
您可以这样包含它:
@Override
public Statement apply(final Statement baseStatement, Description description) {
setUpTestData();
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
if (graphDatabaseService.isAvailable(1000)) {
baseStatement.evaluate();
} else {
Assert.fail("Database was shut down or didn't become available within 1s");
}
} finally {
resetDatabase();
}
}
};
}
public void setUpTestData() {
// can set up common test data here, or just use an @Before method in the test harness
}
public void resetDatabase() {
this.graphDatabaseService.execute("MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE r, n");
}
public class ArbitraryTest {
@Rule
public final Neo4jTestRule neo4jRule = new Neo4jTestRule();
@Test
public void arbitraryTestMethod() {
// some code...
GraphUnit.assertSameGraph(sameGraphCypher, neo4jRule.getGraphDatabaseService());
}
}
请注意,如果您将其作为静态@ClassRule
包含,那么它将对整个测试类只运行一次apply
方法,这可能会更有效,但您必须在@Before
/@After
方法中手动调用reset和setup方法,以在测试运行之间清理问题