[英]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.正在使用
PostgresContainer
和Testcontainers
注释初始化数据库。 However your test infrastructure doesn't know about the database.但是,您的测试基础设施不知道数据库。 If using spring boot, then few things are missed
如果使用 spring 启动,那么会遗漏一些东西
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 injectedSpringBootTest
或DataJpaTest
注释。这样 spring 应用程序上下文将使用正确的类创建, PersonRepository
将被注入static postgresContainer = new PostgreSQLContainer("postgres:12-alpine")
@Shared
PostgreSQLContainer <?> cassandra = cassandraContainer
@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 directory在
application-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.