问题
I have my own custom-written unmanaged extension for Neo4j database.
I want to run integration tests againt fully-functional database, with unmanaged extension available there.
回答1:
Neo4j provides tool called neo4j-harness
that makes it easier to write integration tests for unmanged extensions. More iformation is available here.
Blog post
1) Determine Neo4j version that is needed (used).
Maven:
<properties>
<version.neo4j>2.2.5</version.neo4j>
</properties>
2) Add dependency for neo4j-harness
.
Maven:
<dependency>
<groupId>org.neo4j.test</groupId>
<artifactId>neo4j-harness</artifactId>
<version>${version.neo4j}</version>
<!-- If you want to use Neo4j server in sources, instead of tests, then remove this line -->
<scope>test</scope>
</dependency>
3) Be sure that you unmanaged extension sources is available in tests.
Maven:
If you write tests into same module with extension, then everything is OK.
If you write tests in seperate module (i.e. integration-tests
), then make sure that extension is available there.
<dependency>
<groupId>my.company</groupId>
<artifactId>unmanaged-extension</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
4) Create Neo4jTestServer
class that is responsible for database start-up and shutdown.
/**
* Spin-up Neo4j server with loaded unmanaged extension.
*/
public final class Neo4jTestServer {
public static final String EXTENSION_MOUNT_POINT = "/ext";
public static final String EXTENSION_RESOURCES = "my.company.extension.resources";
// Alternative way to get package
// public static final String EXTENSION_RESOURCES = SomeResource.class.getPackage().getName();
private static Neo4jTestServer INSTANCE = null;
public static synchronized Neo4jTestServer getInstance() {
if (INSTANCE == null) {
INSTANCE = new Neo4jTestServer();
}
return INSTANCE;
}
private final ServerControls serverControls;
private Neo4jTestServer() {
serverControls = TestServerBuilders.newInProcessBuilder()
.withExtension(EXTENSION_MOUNT_POINT, EXTENSION_RESOURCES)
// Resource can be specified directly
// .withExtension(EXTENSION_MOUNT_POINT, SomeResource.class)
.newServer();
}
public ServerControls getServerControls() {
return serverControls;
}
public void shutdown() {
serverControls.close();
}
}
Usage:
Neo4jTestServer server = Neo4jTestServer.getInstance();
// Get Neo4j server URI, with port
server.getServerControls().getHttpUri();
// Shutdown server
server.shutdown();
Notes:
SomeResource
is JAX-RS resource that provides custom functionality- If you have more than 1 resource, and want to use class to specify unmanaged extension, instead of string - there is no need to specify all thoose classes. Neo4j will scan specified class package for other resources and load them automatically.
- All resources should be in same package
Tip: You can create ResourcesRootPackageMarker
class in same package, where all resources reside and use this class to specify package. It makes code more resilient to future code refactorings.
5) Optional. Specify JVM shutdown hook to shutdown database.
final Neo4jTestServer server = Neo4jTestServer.getInstance();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
server.shutdown();
}
});
6) To verify that everything is working and your unmanaged extension is available - execute tests, start database and examine output generated by Neo4j server.
You should see something like this:
INFO: Scanning for root resource and provider classes in the packages:
my.company.extension.resources
Sep 14, 2015 5:25:15 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class my.company.extension.resources.SomeResource
class my.company.extension.resources.AnotherResource
EDIT: Graphaware test framework, information provided by MicTech
Alternatively, there is GraphAware Test framework provided by graphaware, that gives possibility to test any Neo4j-related code.
This module provides means of easily testing code that talks to the Neo4j database in one way or another. The target audience of this module are Java developers who write Neo4j-related code, as well as authors of GraphAware Modules and APIs.
Here you can find some posts about how framework can be used (autored by Graphaware developers).
Basically what you need to do is:
1) Create extension:
@Path("/helloworld")
public class HelloWorldUnmanagedExtension {
private final HelloWorldNodeCreator nodeCreator;
public HelloWorldUnmanagedExtension(@Context GraphDatabaseService database) {
nodeCreator = new HelloWorldNodeCreator(database);
}
@POST
@Path("/create")
public Response createHelloWorldNode() {
Node node = nodeCreator.createHelloWorldNode();
return Response.ok(String.valueOf(node.getId())).build();
}
}
2) Extend your test with WrappingServerIntegrationTest
and necessary configuration.
public class HelloWorldUnmanagedExtensionApiTest extends WrappingServerIntegrationTest {
@Override
protected Map<String, String> thirdPartyJaxRsPackageMappings() {
return Collections.singletonMap("com.graphaware.example.unmanaged", "/ext");
}
@Test
public void shouldCreateAndReturnNode() {
String result = TestUtils.post(baseNeoUrl() + "/ext/helloworld/create", 200);
assertEquals("0", result);
GraphUnit.assertSameGraph(getDatabase(), "CREATE (:HelloWorld {hello:'world'})");
}
}
Here can be found more detailed instructions on how to test unmanaged extension with Graphaware test framework.
Everything should be up-and-running now and ready for testing. Good luck!
来源:https://stackoverflow.com/questions/32567424/how-to-run-tests-against-neo4j-with-custom-unmanaged-extension