Spring Boot 使用Spock执行单元测试时,JpaRepository未被注入,并返回空值

lf3rwulv  于 2023-02-04  发布在  Spring
关注(0)|答案(2)|浏览(178)

在我使用Spock和Testcontainers进行单元测试期间,JpaRepository运行不正常,并且没有正确连接,即使在非集成测试中,这个问题也会持续存在。
正如在另一次讨论中所建议的,我试图通过向pom.xml文件添加spock-spring依赖项来解决这个问题,但没有成功。
不管是什么场景,存储库在所有示例中都一致地返回null。

示例:

@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
    }
}
vuktfyat

vuktfyat1#

正在使用PostgresContainerTestcontainers注解初始化数据库。但是,您的测试基础结构不知道该数据库。如果使用spring boot,则会遗漏一些内容
1.在类的顶部添加SpringBootTestDataJpaTest注解,这样就可以使用正确的类创建spring应用程序上下文,并注入PersonRepository
1.切换到

static postgresContainer = new PostgreSQLContainer("postgres:12-alpine")

@Shared
PostgreSQLContainer <?> cassandra = cassandraContainer

1.为了利用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);
}
kuarbcqp

kuarbcqp2#

我建议像下面这样分离容器设置:
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() {
    }
}

在测试文件中扩展PostgresEnvironment

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

  // autowire jpa
  // write tests
}

在test目录下的参考资料部分的application-test.yml文件中

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

还要确保在启动应用程序时使用的主application.yml文件(不是用于运行测试的)与测试概要文件的语法匹配。

相关问题