I am trying to run some tests in the same class using Neo4jRule to initialize the graph. Using @Rule
for Neo4jRule
variable, @Before
and @After
methods, the initialization runs before each test. I want the initialization to run once for all tests. I know that I can use annotations @ClassRule
for Neo4jRule
variable, @BeforeClass
and @AfterClass
and make all of them static
, but I get the message:
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)
The line 65 at the 2nd version of code is:
driver = GraphDatabase.driver(
neo4j.boltURI(),
Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig()
);
Which is the right way to initialize once the graph? Ideally, I would like to have the code in one class and use it in many test classes.
Code using @Rule
, @Before
and @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();
}
Code using @ClassRule
, @BeforeClass
and @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();
}