Neo4j: unit testing the bolt driver properly

2.8k Views Asked by At

I am adding the Neo4j Bolt driver to my application just following the http://neo4j.com/developer/java/:

import org.neo4j.driver.v1.*;

Driver driver = GraphDatabase.driver( "bolt://localhost", AuthTokens.basic( "neo4j", "neo4j" ) );

Session session = driver.session();
session.run( "CREATE (a:Person {name:'Arthur', title:'King'})" );

StatementResult result = session.run( "MATCH (a:Person) WHERE a.name = 'Arthur' RETURN a.name AS name, a.title AS title" );

while ( result.hasNext() )

{
    Record record = result.next();
    System.out.println( record.get( "title" ).asString() + " " + record.get("name").asString() );
}
session.close();
driver.close();

However, always from the official documentation unit testing is made using:

GraphDatabaseService db = new TestGraphDatabaseFactory()
            .newImpermanentDatabaseBuilder()

So if I want to test in some way the code above, I have to replace the GraphDatabase.driver( "bolt://localhost",...) with the GraphDatabaseService from the test. How can I do that? I cannot extract any sort of in-memory driver from there as far as I can see.

2

There are 2 best solutions below

7
On BEST ANSWER

The Neo4j JDBC has a class called Neo4jBoltRule for unit testing. It is a junit rule starting/stopping an impermanent database together with some configuration to start bolt.

The rule class uses dynamic port assignment to prevent test failure due to running multiple tests in parallel (think of your CI infrastructure).

An example of a unit test using that rule class is available at https://github.com/neo4j-contrib/neo4j-jdbc/blob/master/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java

0
On

An easy way now is to pull neo4j-harness, and use their built-in Neo4jRule as follows:

import static org.neo4j.graphdb.factory.GraphDatabaseSettings.boltConnector;
// [...]
@Rule public Neo4jRule graphDb = new Neo4jRule()
        .withConfig(boltConnector("0").address, "localhost:" + findFreePort());

Where findFreePort implementation can be as simple as:

private static int findFreePort() {
    try (ServerSocket socket = new ServerSocket(0)) {
        return socket.getLocalPort();
    } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}

As the Javadoc of ServerSocket explains:

A port number of 0 means that the port number is automatically allocated, typically from an ephemeral port range. This port number can then be retrieved by calling getLocalPort.

Moreover, the socket is closed before the port value is returned, so there are great chances the returned port will still be available upon return (the window of opportunity for the port to be allocated again in between is small - the computation of the window size is left as an exercise to the reader).

Et voilà !