Testcontainers module for Neo4j graph database integration, providing lightweight throwaway Neo4j instances for JUnit tests
npx @tessl/cli install tessl/maven-org-testcontainers--neo4j@1.21.0A Java library module providing lightweight, throwaway Neo4j graph database instances for testing. The Neo4j Testcontainers module integrates with JUnit to create isolated Neo4j database containers that start automatically for tests and clean up afterward, supporting both Community and Enterprise editions.
pom.xml:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>neo4j</artifactId>
<version>1.21.3</version>
<scope>test</scope>
</dependency>For Gradle:
testImplementation 'org.testcontainers:neo4j:1.21.3'import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.containers.Neo4jLabsPlugin;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;
import org.testcontainers.containers.wait.strategy.WaitStrategy;import org.testcontainers.containers.Neo4jContainer;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
public class Neo4jTest {
@Test
public void testWithNeo4j() {
try (Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.4")) {
neo4jContainer.start();
// Get connection details
String boltUrl = neo4jContainer.getBoltUrl();
String password = neo4jContainer.getAdminPassword();
// Connect and run query
try (Driver driver = GraphDatabase.driver(boltUrl, AuthTokens.basic("neo4j", password));
Session session = driver.session()) {
session.run("CREATE (n:Person {name: 'Test'})");
Result result = session.run("MATCH (n:Person) RETURN n.name AS name");
// Process results...
}
}
}
}The Neo4j Testcontainers module follows the standard Testcontainers architecture:
Create and configure Neo4j container instances with various Docker images and settings.
/**
* Testcontainers implementation for Neo4j.
* Supported image: neo4j
* Exposed ports: Bolt (7687), HTTP (7474), HTTPS (7473)
*
* @param <S> Self-type for method chaining
*/
public class Neo4jContainer<S extends Neo4jContainer<S>> extends GenericContainer<S> {
/**
* Creates a Neo4jContainer using the official Neo4j docker image.
* @deprecated use Neo4jContainer(DockerImageName) instead
*/
@Deprecated
public Neo4jContainer();
/**
* Creates a Neo4jContainer using a specific docker image.
* @param dockerImageName The docker image to use
*/
public Neo4jContainer(String dockerImageName);
/**
* Creates a Neo4jContainer using a specific docker image.
* @param dockerImageName The docker image to use
*/
public Neo4jContainer(DockerImageName dockerImageName);
/**
* Configures the container to use the enterprise edition.
* Requires license acceptance.
* @return This container
*/
public S withEnterpriseEdition();
}Configure Neo4j authentication settings including custom passwords, random passwords, or disabled authentication.
/**
* Sets the admin password for the default account (neo4j).
* @param adminPassword The admin password (minimum 8 characters for Neo4j 5.3+)
* @return This container
*/
public S withAdminPassword(String adminPassword);
/**
* Disables authentication.
* @return This container
*/
public S withoutAuthentication();
/**
* Sets a random UUID-based password.
* @return This container
*/
public S withRandomPassword();
/**
* Gets the admin password for the neo4j account.
* @return The admin password or null if auth is disabled
*/
public String getAdminPassword();Usage Example:
// Custom password
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:4.4")
.withAdminPassword("mySecretPassword");
// Disable authentication
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:4.4")
.withoutAuthentication();
// Random UUID-based password
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:4.4")
.withRandomPassword();Get connection URLs for different Neo4j protocols and endpoints.
/**
* Gets the Bolt URL for use with Neo4j's Java-Driver.
* @return Bolt URL in format: bolt://host:port
*/
public String getBoltUrl();
/**
* Gets the URL of the transactional HTTP endpoint.
* @return HTTP URL in format: http://host:port
*/
public String getHttpUrl();
/**
* Gets the URL of the transactional HTTPS endpoint.
* @return HTTPS URL in format: https://host:port
*/
public String getHttpsUrl();Usage Example:
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:4.4");
container.start();
// For Neo4j Java Driver (Bolt protocol)
String boltUrl = container.getBoltUrl();
Driver driver = GraphDatabase.driver(boltUrl, AuthTokens.basic("neo4j", "password"));
// For HTTP REST API
String httpUrl = container.getHttpUrl();
// Make HTTP requests to httpUrl + "/db/data/transaction/commit"
// For HTTPS REST API
String httpsUrl = container.getHttpsUrl();Add existing databases, custom plugins, and Neo4j Labs plugins to the container.
/**
* Copies an existing graph.db folder into the container.
* Note: Only works with Neo4j 3.5.x
* @param graphDb The graph.db folder to copy
* @return This container
* @throws IllegalArgumentException If the database version is not 3.5
*/
public S withDatabase(MountableFile graphDb);
/**
* Adds plugins from a directory or file to the container.
* @param plugins Plugin directory or JAR file to copy
* @return This container
*/
public S withPlugins(MountableFile plugins);
/**
* Registers one or more Neo4j plugins for server startup.
* @param plugins Plugin names (e.g., "apoc", "graph-data-science")
* @return This container
*/
public S withPlugins(String... plugins);
/**
* Registers Neo4j Labs plugins using enum values.
* @param neo4jLabsPlugins Plugin enum values
* @return This container
* @deprecated Use withPlugins(String...) with plugin names instead
*/
@Deprecated
public S withLabsPlugins(Neo4jLabsPlugin... neo4jLabsPlugins);
/**
* Registers Neo4j Labs plugins using string names.
* @param neo4jLabsPlugins Plugin names
* @return This container
* @deprecated Use withPlugins(String...) instead
*/
@Deprecated
public S withLabsPlugins(String... neo4jLabsPlugins);Usage Example:
// Copy existing database (Neo4j 3.5 only)
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:3.5.30")
.withDatabase(MountableFile.forClasspathResource("/test-graph.db"));
// Add custom plugins
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:4.4")
.withPlugins(MountableFile.forClasspathResource("/custom-plugins"));
// Add Neo4j Labs plugins by name
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:4.4")
.withPlugins("apoc", "graph-data-science");Set Neo4j-specific configuration options using the standard Neo4j configuration format.
/**
* Adds Neo4j configuration properties to the container.
* Properties are automatically translated to the format required by the Neo4j container.
* @param key The configuration key (e.g., "dbms.security.procedures.unrestricted")
* @param value The configuration value
* @return This container
*/
public S withNeo4jConfig(String key, String value);Usage Example:
Neo4jContainer<?> container = new Neo4jContainer<>("neo4j:4.4")
.withNeo4jConfig("dbms.security.procedures.unrestricted", "apoc.*,algo.*")
.withNeo4jConfig("dbms.tx_log.rotation.size", "42M")
.withNeo4jConfig("dbms.memory.heap.initial_size", "1G")
.withNeo4jConfig("dbms.memory.heap.max_size", "2G");Standard container lifecycle methods and information access inherited from GenericContainer.
// Inherited lifecycle methods (from GenericContainer)
public void start();
public void stop();
public void restart();
public boolean isRunning();
/**
* Gets the ports used for liveness checks.
* @return Set of port numbers used for health checks
*/
public Set<Integer> getLivenessCheckPortNumbers();
// Inherited port and network information (from GenericContainer)
public Integer getMappedPort(int originalPort);
public String getHost();
/**
* Configures the container's internal settings.
* Called automatically during container startup.
*/
protected void configure();/**
* Reflects a plugin from the official Neo4j 4.4.
* @deprecated Use withPlugins(String...) with matching plugin name for your Neo4j version
*/
@Deprecated
public enum Neo4jLabsPlugin {
APOC("apoc"),
APOC_CORE("apoc-core"),
BLOOM("bloom"),
STREAMS("streams"),
GRAPH_DATA_SCIENCE("graph-data-science"),
NEO_SEMANTICS("n10s");
final String pluginName;
Neo4jLabsPlugin(String pluginName);
}/**
* Default wait strategy for Bolt protocol readiness.
* Waits for log message indicating Bolt is enabled on port 7687.
*/
public static final WaitStrategy WAIT_FOR_BOLT;
// Default ports (private constants, accessed via getMappedPort())
private static final int DEFAULT_BOLT_PORT = 7687;
private static final int DEFAULT_HTTP_PORT = 7474;
private static final int DEFAULT_HTTPS_PORT = 7473;
// Default configuration (private constants)
private static final String DEFAULT_ADMIN_PASSWORD = "password";
private static final String DEFAULT_TAG = "4.4";
private static final String ENTERPRISE_TAG = "4.4-enterprise";
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("neo4j");Common exceptions and error scenarios:
withDatabase() with Neo4j 4.0+ (only supports 3.5.x)withDatabase()public class Neo4jIntegrationTest {
@ClassRule
public static Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.4");
@Test
public void testDatabaseQuery() {
try (Driver driver = GraphDatabase.driver(
neo4jContainer.getBoltUrl(),
AuthTokens.basic("neo4j", neo4jContainer.getAdminPassword()));
Session session = driver.session()) {
Result result = session.run("RETURN 1 AS number");
assertEquals(1L, result.single().get("number").asLong());
}
}
}@Testcontainers
class Neo4jTest {
@Container
static Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.4")
.withAdminPassword("testPassword")
.withPlugins("apoc");
@Test
void testWithApocPlugin() {
try (Driver driver = GraphDatabase.driver(
neo4jContainer.getBoltUrl(),
AuthTokens.basic("neo4j", "testPassword"));
Session session = driver.session()) {
// Test APOC functionality
Result result = session.run("RETURN apoc.version() AS version");
assertNotNull(result.single().get("version").asString());
}
}
}