如何将Neo4jRule与@ClassRule注释一起使用

时间:2016-05-27 22:05:41

标签: neo4j

我正在尝试使用Neo4jRule在同一个类中运行一些测试来初始化图形。对@Rule变量,Neo4jRule@Before方法使用@After,初始化在每次测试之前运行。我希望初始化为所有测试运行一次。我知道我可以对@ClassRule变量,Neo4jRule@BeforeClass使用注释@AfterClass并使所有这些变量static,但我收到消息:

java.lang.IllegalStateException: Cannot access instance URI before or after the test runs.

at org.neo4j.harness.junit.Neo4jRule.boltURI(Neo4jRule.java:154)
at FullTextIndexTest.before(FullTextIndexTest.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

第二版代码的第65行是:

driver = GraphDatabase.driver(
            neo4j.boltURI(),
            Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig()
    );

图表初始化的正确方法是什么?理想情况下,我希望将代码放在一个类中,并在许多测试类中使用它。

使用@Rule@Before@After的代码:

@Rule
public Neo4jRule neo4j;
private Driver driver;
private Session session;

public FullTextIndexTest() {
    InputStream resource = this.getClass().getResourceAsStream("/graph.cypher");
    StringBuilder cypher = new StringBuilder();
    Scanner scanner = new Scanner(resource).useDelimiter("\n");
    while (scanner.hasNext()) {
        cypher.append(scanner.next()).append("\n");
    }
    neo4j = new Neo4jRule().withFixture(cypher.toString());
}

@Before
public void before() {
    driver = GraphDatabase.driver(
            neo4j.boltURI(),
            Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig()
    );
    session = driver.session();
    // Start indexing
    GraphDatabaseService db = neo4j.getGraphDatabaseService();
    try (org.neo4j.graphdb.Transaction tx = db.beginTx()) {
        // Index nodes
        Index<Node> ftiNodes = db.index().forNodes(NODES_INDEX, FULL_TEXT);
        ResourceIterable<Node> allNodes = db.getAllNodes();
        for (Node node : allNodes) {
            // Index all node's properties
            Map<String, Object> allProperties = node.getAllProperties();
            for (Map.Entry<String, Object> property : allProperties.entrySet()) {
                ftiNodes.add(node, property.getKey(), property.getValue());
            }
        }
        tx.success();
    }

    try (org.neo4j.graphdb.Transaction tx = db.beginTx()) {
        // Index relationships
        RelationshipIndex ftiRels = db.index().forRelationships(RELS_INDEX, FULL_TEXT);
        ResourceIterable<Relationship> allRelationships = db.getAllRelationships();
        for (Relationship relationship : allRelationships) {
            Map<String, Object> allProperties = relationship.getAllProperties();
            for (Map.Entry<String, Object> property : allProperties.entrySet()) {
                ftiRels.add(relationship, property.getKey(), property.getValue());
            }
        }

        tx.success();
    }
}

@After
public void after() {
    driver.close();
}

使用@ClassRule@BeforeClass@AfterClass的代码:

@ClassRule
public static Neo4jRule neo4j;
private static Driver driver;
private static Session session;

@BeforeClass
public static void before() {
    InputStream resource = FullTextIndexTest.class.getResourceAsStream("/graph.cypher");
    StringBuilder cypher = new StringBuilder();
    Scanner scanner = new Scanner(resource).useDelimiter("\n");
    while (scanner.hasNext()) {
        cypher.append(scanner.next()).append("\n");
    }
    neo4j = new Neo4jRule().withFixture(cypher.toString());
    driver = GraphDatabase.driver(
            neo4j.boltURI(),
            Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig()
    );
    session = driver.session();
    // Start indexing
    GraphDatabaseService db = neo4j.getGraphDatabaseService();
    try (org.neo4j.graphdb.Transaction tx = db.beginTx()) {
        // Index nodes
        Index<Node> ftiNodes = db.index().forNodes(NODES_INDEX, FULL_TEXT);
        ResourceIterable<Node> allNodes = db.getAllNodes();
        for (Node node : allNodes) {
            // Index all node's properties
            Map<String, Object> allProperties = node.getAllProperties();
            for (Map.Entry<String, Object> property : allProperties.entrySet()) {
                ftiNodes.add(node, property.getKey(), property.getValue());
            }
        }
        tx.success();
    }

    try (org.neo4j.graphdb.Transaction tx = db.beginTx()) {
        // Index relationships
        RelationshipIndex ftiRels = db.index().forRelationships(RELS_INDEX, FULL_TEXT);
        ResourceIterable<Relationship> allRelationships = db.getAllRelationships();
        for (Relationship relationship : allRelationships) {
            Map<String, Object> allProperties = relationship.getAllProperties();
            for (Map.Entry<String, Object> property : allProperties.entrySet()) {
                ftiRels.add(relationship, property.getKey(), property.getValue());
            }
        }

        tx.success();
    }
}

@AfterClass
public static void after() {
    driver.close();
}

1 个答案:

答案 0 :(得分:0)

问题是static方法中 neo4j @BeforeClass public static void before()变量的初始化。正确的方法是使用静态初始化程序块。

错误:

@ClassRule
public static Neo4jRule neo4j;
private static Driver driver;

@BeforeClass
public static void before() {
    // Read you resource file (named cypher here)
    neo4j = new Neo4jRule().withFixture(cypher);
    driver = GraphDatabase.driver(
            neo4j.boltURI(),
            Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig()
    );
    // rest of your code
}

@AfterClass
public static void after() {
    driver.close();
}    

正确

@ClassRule
public static Neo4jRule neo4j;
private static Driver driver;

static {
    // Read you resource file (named cypher here)
    neo4j = new Neo4jRule().withFixture(cypher);
}

@BeforeClass
public static void before() {
    driver = GraphDatabase.driver(
            neo4j.boltURI(),
            Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig()
    );
    // rest of your code
}

@AfterClass
public static void after() {
    driver.close();
}