Neo4j:正确地对螺栓驱动器进行单元测试
Neo4j: unit testing the bolt driver properly
我正在将 Neo4j Bolt 驱动程序添加到我的应用程序中,紧接着 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();
但是,官方 documentation 单元测试总是使用:
GraphDatabaseService db = new TestGraphDatabaseFactory()
.newImpermanentDatabaseBuilder()
所以如果我想以某种方式测试上面的代码,我必须用测试中的 GraphDatabaseService
替换 GraphDatabase.driver( "bolt://localhost",...)
。我怎样才能做到这一点?据我所知,我无法从那里提取任何类型的 in-memory driver
。
Neo4j JDBC 有一个名为 Neo4jBoltRule 的 class 用于单元测试。这是一个 junit 规则 starting/stopping 一个临时数据库和一些启动 bolt 的配置。
规则 class 使用动态端口分配来防止由于 运行 多个并行测试而导致的测试失败(想想您的 CI 基础设施)。
使用该规则 class 的单元测试示例可在 https://github.com/neo4j-contrib/neo4j-jdbc/blob/master/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java
获得
现在一个简单的方法是拉取 neo4j-harness
,然后使用它们的内置 Neo4jRule
,如下所示:
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.boltConnector;
// [...]
@Rule public Neo4jRule graphDb = new Neo4jRule()
.withConfig(boltConnector("0").address, "localhost:" + findFreePort());
其中 findFreePort
实现可以像这样简单:
private static int findFreePort() {
try (ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
正如 ServerSocket
的 Javadoc 所解释的:
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.
此外,套接字在端口值被 returned 之前关闭,因此 returned 端口很有可能在 return 时仍然可用(window 之间再次分配端口的机会很小 - window 大小的计算留作 reader) 的练习。
瞧瞧!
我正在将 Neo4j Bolt 驱动程序添加到我的应用程序中,紧接着 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();
但是,官方 documentation 单元测试总是使用:
GraphDatabaseService db = new TestGraphDatabaseFactory()
.newImpermanentDatabaseBuilder()
所以如果我想以某种方式测试上面的代码,我必须用测试中的 GraphDatabaseService
替换 GraphDatabase.driver( "bolt://localhost",...)
。我怎样才能做到这一点?据我所知,我无法从那里提取任何类型的 in-memory driver
。
Neo4j JDBC 有一个名为 Neo4jBoltRule 的 class 用于单元测试。这是一个 junit 规则 starting/stopping 一个临时数据库和一些启动 bolt 的配置。
规则 class 使用动态端口分配来防止由于 运行 多个并行测试而导致的测试失败(想想您的 CI 基础设施)。
使用该规则 class 的单元测试示例可在 https://github.com/neo4j-contrib/neo4j-jdbc/blob/master/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java
获得现在一个简单的方法是拉取 neo4j-harness
,然后使用它们的内置 Neo4jRule
,如下所示:
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.boltConnector;
// [...]
@Rule public Neo4jRule graphDb = new Neo4jRule()
.withConfig(boltConnector("0").address, "localhost:" + findFreePort());
其中 findFreePort
实现可以像这样简单:
private static int findFreePort() {
try (ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
正如 ServerSocket
的 Javadoc 所解释的:
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.
此外,套接字在端口值被 returned 之前关闭,因此 returned 端口很有可能在 return 时仍然可用(window 之间再次分配端口的机会很小 - window 大小的计算留作 reader) 的练习。
瞧瞧!