简体   繁体   English

使用 Spock 执行单元测试时,JpaRepository 未被注入并返回为 null

[英]When performing unit testing using Spock, JpaRepository is not being injected and is returning as null

During my unit tests using Spock and Testcontainers, the JpaRepository is not functioning properly and is not being wired correctly.在我使用 Spock 和 Testcontainers 进行单元测试期间,JpaRepository 无法正常运行并且未正确连接。 This issue persists even in non-integration tests.这个问题甚至在非集成测试中仍然存在。

As suggested in another discussion, I attempted to resolve the issue by adding the spock-spring dependency to my pom.xml file.正如另一个讨论中所建议的那样,我试图通过将 spock-spring 依赖项添加到我的 pom.xml 文件来解决这个问题。 It didn't work.它没有用。

No matter the scenario, the repository consistently returns as null in all instances.无论哪种情况,存储库在所有实例中始终返回 null。

An example:一个例子:

@Testcontainers
class PostgresTestContainer extends Specification {

    @Autowired
    private PersonRepository personRepository

    @Shared
    PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer("postgres:12-alpine")
            .withDatabaseName("test")
            .withUsername("test")
            .withPassword("test")

    def "waits until postgres accepts jdbc connections"() {

        when: "querying the database"
        def response = personRepository.findAll()

        then: "result is returned"
        response == 0
    }
}

The database is being initialized using PostgresContainer and Testcontainers annotation.正在使用PostgresContainerTestcontainers注释初始化数据库。 However your test infrastructure doesn't know about the database.但是,您的测试基础设施不知道数据库。 If using spring boot, then few things are missed如果使用 spring 启动,那么会遗漏一些东西

  1. Add SpringBootTest or DataJpaTest annotation on top of the class. This way the spring application context is created with the right classes and PersonRepository will be injected在 class 之上添加SpringBootTestDataJpaTest注释。这样 spring 应用程序上下文将使用正确的类创建, PersonRepository将被注入
  2. Switch to切换到
static postgresContainer = new PostgreSQLContainer("postgres:12-alpine")

@Shared
PostgreSQLContainer <?> cassandra = cassandraContainer
  1. In order to make use of the database provided by Testcontainers, add为了使用 Testcontainers 提供的数据库,添加
@DynamicPropertySource
static void registerProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.datasource.url", postgresContainer::getJdbcUrl);
    registry.add("spring.datasource.username", postgresContainer::getUsername);
    registry.add("spring.datasource.password", postgresContainer::getPassword);
}

I would suggest to separate the container setup like the following:我建议像下面这样分离容器设置:

PostgresEnvrionement

@Testcontainers
public class PostgresEnvironment {

    @Container
    public static PostgreSQLContainer postgreSQLContainer = PostgresTestContainer.getInstance();
}

PostgresTestContainer

public class PostgresTestContainer extends PostgreSQLContainer<PostgresTestContainer> {

    public static final String IMAGE_VERSION = "postgres:13.5";
    public static final String DATABASE_NAME = "test";
    private static PostgresTestContainer container;

    private PostgresTestContainer() {
        super(IMAGE_VERSION);
    }

    public static PostgresTestContainer getInstance() {
        if (container == null) {
            container = new PostgresTestContainer().withDatabaseName(DATABASE_NAME);
        }
        return container;
    }

    @Override
    public void start() {
        super.start();
        System.setProperty("DB_URL", container.getJdbcUrl());
        System.setProperty("DB_USERNAME", container.getUsername());
        System.setProperty("DB_PASSWORD", container.getPassword());
    }

    @Override
    public void stop() {
    }
}

In your test file extend the PostgresEnvironment在您的测试文件中扩展PostgresEnvironment

@ActiveProfiles("test")
@SpringBootTest(classes = MainSpringBootApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AssembleEventRepositoryIntegrationTest extends PostgresEnvrionement{

  // autowire jpa
  // write tests
}

in your application-test.yml file in the resources section under the test directoryapplication-test.yml文件中,在 test 目录下的 resources 部分

spring:
  datasource:
    password: ${DB_USERNAME}
    username: ${DB_PASSWORD}
    driver-class-name: org.postgresql.Driver
    url: ${DB_URL}

Also make sure that your main application.yml file that is being used once launching your application (not in for running your tests) matches the same syntax as your test profile.还要确保启动应用程序后使用的主要application.yml文件(不是用于运行测试)与测试配置文件匹配相同的语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在单元测试时使用 Spock 访问通过属性文件访问的全局定义的属性 - How can I access a globally defined property that is accessed through a property file using Spock when unit testing 无法在 spock 中使用注解 @Autowired 注入 JpaRepository - Cannot inject JpaRepository using annotation @Autowired in spock JpaRepository未在componentscan的独立包中实现/注入 - JpaRepository not implemented/injected when in separate package from componentscan sessionFactory没有被注入。 永远为空 - sessionFactory not being injected. It's always null 如何在 Spring Boot 单元测试中模拟构造函数注入的 @Value 属性 - How to mock constructor injected @Value property in Spring Boot Unit Testing Spring 引导响应实体在单元测试时返回 Null Rest Z9BBF373797BF7CF7BA62C800236 - Spring Boot Response Entity Is Returning Null While Unit Testing Rest Controller @Value在单元测试中返回null - @Value returning null in unit test 使用 JpaRepository 更新时事务提交错误 - Transaction commit error when updating using JpaRepository 即使我在测试时使用现有记录,Spring Data Jpa自定义查询方法仍返回null - Spring Data Jpa custom query method returning null even though I am using an existing record when testing 当在JPARepository上进行间谍监视时,调用save方法返回null - When Spying on a JPARepository calling the save method returns null
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM