使用 Spring 引导和嵌入式驱动程序测试 Neo4j

Testing Neo4j with Spring Boot and embedded driver

问题

我使用 Neo4j 数据库构建了一个应用程序。我喜欢使用 Spring Boot 的 @DataNeo4jTest 注释(另请参阅 Spring Boot Test - Neo4j)来测试一些自定义 Cypher 查询,但我 运行 遇到以下任一问题:

详情

我的依赖项是在 Spring Data Neo4j Reference Documentation 之后使用 Maven 管理的。 SDN 文档第 10.3.1 节解释:

By default, SDN will use the BOLT driver to connect to Neo4j and you don’t need to declare it as a separate dependency in your pom. If you want to use the embedded or HTTP drivers in your production application, you must add the following dependencies as well. (This dependency on the embedded driver is not required if you only want to use the embedded driver for testing. See the section on Testing below for more information).

因此,我的pom.xml的相关部分是:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi=...>
    ...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        ...
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-neo4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.neo4j.test</groupId>
            <artifactId>neo4j-harness</artifactId>
            <version>3.3.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    ...
</project>

我的main/resources/application.yml是:

spring:
    data:
        neo4j:
            uri: bolt://localhost
            username: <username>
            password: <password>

我的test/resources/application.yml是:

spring.data.neo4j.uri: file:///neo4j.db

没有 test/resources/application.yml 我得到以下异常,我认为这是由使用 BOLT 驱动程序引起的:

org.springframework.transaction.CannotCreateTransactionException: Could not open Neo4j Session for transaction;
    nested exception is org.neo4j.driver.v1.exceptions.AuthenticationException: The client is unauthorized due to authentication failure.

使用 test/resources/application.yml 我得到以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'neo4jAuditionBeanFactoryPostProcessor': Unsatisfied dependency expressed through constructor parameter 0;
    nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.class]: Bean instantiation via factory method failed;
    nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception;
    nested exception is org.neo4j.ogm.exception.core.ConfigurationException: Could not load driver class org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver

问题

欢迎提出任何建议。

我找到了解决问题的方法。似乎 BOLT 驱动程序也被用作测试的默认值 - 考虑到 Spring Data Neo4j (SDN) 文档,这令人困惑。最后,GitHub项目movies-java-spring-data-neo4jpom.xml帮助了我。我将以下测试依赖项添加到我的 pom.xml:

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-ogm-embedded-driver</artifactId>
    <version>${neo4j-ogm.version}</version>
    <scope>test</scope>
</dependency>

我保留了 test/resources/application.yml 删除了 行:

spring.data.neo4j.uri: file:///neo4j.db

现在,测试上下文从嵌入式驱动程序开始,并创建一个类似于 file:/C:/Users/Me/AppData/Local/Temp/neo4j.db6943517458205762238/ 的临时数据库文件,这太棒了。我可以为每个测试方法获得一个干净的数据库实例。

希望这个回答能对遇到同样问题的其他人有所帮助。如有必要,我很乐意提供更多详细信息。

@DataNeo4JTest 与 Spring Boot 2.x.

配合使用效果很好

示例测试:

@RunWith(SpringRunner.class)
@DataNeo4jTest
public class WidgetRepositoryTest {

  @Autowired
  private WidgetRepository repository;

  private Widget widget;

  @Before
  public void setUp() {
    widget = WidgetTestData.builder().build();
  }

  @Test
  public void itShouldSaveAndRetrieve() {

    final Widget saved = repository.save(widget);
    assertThat(saved.getId()).isNotNull();
    assertThat(saved.getName()).isEqualTo(widget.getName());

    final Optional<Widget> found = repository.findById(saved.getId());
    assertThat(found).hasValueSatisfying(w-> {
      assertThat(w.getId()).isEqualTo(saved.getId());
      assertThat(w.getName()).isEqualTo(saved.getName());
    });
  }
}

我的 Maven POM 中与 Neo4J 相关的依赖项:

<dependency>
  <groupId>org.neo4j.test</groupId>
  <artifactId>neo4j-harness</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.neo4j</groupId>
  <artifactId>neo4j-ogm-embedded-driver</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>