Home > Blockchain >  When performing unit testing using Spock, JpaRepository is not being injected and is returning as nu
When performing unit testing using Spock, JpaRepository is not being injected and is returning as nu

Time:02-01

During my unit tests using Spock and Testcontainers, the JpaRepository is not functioning properly and is not being wired correctly. 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. It didn't work.

No matter the scenario, the repository consistently returns as null in all instances.

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

CodePudding user response:

The database is being initialized using PostgresContainer and Testcontainers annotation. However your test infrastructure doesn't know about the database. If using spring boot, then few things are missed

  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
  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
@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);
}

CodePudding user response:

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

@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

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.

  • Related