【问题标题】:GraphUnit - transactional integration tests and rollbacksGraphUnit - 事务集成测试和回滚
【发布时间】:2015-07-16 19:05:51
【问题描述】:

我目前正在使用 GraphUnit、Spock 和一个进程中的 Neo4j 服务器对我的 Spring Data Neo4j 4.0 支持的应用程序进行集成测试。

在我的测试操作之后对图形数据库的状态进行断言是一个非常好的工具,但我注意到为了让 GraphUnit 的 assertGraphprintGraph 向我展示我的期望,我的 Neo4j 事务必须先提交。从逻辑上讲,这对我来说是有意义的,但这也意味着我无法标记我的集成测试@Transactional,并且在一次测试中对进程中数据库所做的任何数据更改都会影响到后续测试。

我通过在 Spock 夹具方法中的每个测试方法之后清除数据库来处理这个问题,这工作正常,但我非常希望能够:

  • 设置测试 Neo4j 数据集 ONCE
  • 在每次测试后回滚测试方法更改
  • 仍然能够以某种方式使用 GraphUnit 的断言和打印实用程序

我的问题是 - 有没有办法完成这三个方面?如果我想使用 GraphUnit,事务提交是否是一个基本要求/假设?

【问题讨论】:

    标签: neo4j spring-data-neo4j-4 graphaware


    【解决方案1】:

    虽然您可以毫不费力地管理测试方法之间的 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());
        }
    
    }
    

    请注意,如果您将其作为静态 @ClassRule 包含在内,那么它将为整个测试类只运行一次 apply 方法,这可能更有效,但您必须调用 reset 和 setup 方法在 @Before / @After 方法中手动清理测试运行之间的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2011-05-07
      • 2018-09-15
      • 1970-01-01
      相关资源
      最近更新 更多