User
User

Reputation: 1

Creating a table in integration test before post construct of main component

I have a component where I have this code

@PostConstruct
    public void initWeekMonthData() {

        testData = repository.findAllActiveRecords();

    }

Now I'm trying to write integration test but while my application is booting up I'm getting error Table "test_data" not found

I have this table creation script in my schema.sql and data script in data.sql

My integration test class code:

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test-containers")
@Testcontainers
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Sql({"/schema.sql", "/data.sql"})
@DirtiesContext
public class IntegrationTest {

    private static final String BKA_DEMAND_API_URI = "/v2/demand-data";

    @Autowired
    MockMvc mockMvc;

    @DynamicPropertySource
    static void properties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", sqlContainer()::getJdbcUrl);
        registry.add("spring.datasource.username", sqlContainer()::getUsername);
        registry.add("spring.datasource.password", sqlContainer()::getPassword);
    }

    @BeforeAll
    static void setup() throws IOException, InterruptedException {
    }

    @Order(1)
    @Test
    void getDataTest() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders
                        .get(URI)
                        .param(TEST, "1234"))
                .andExpect(status().isOk());
    }

}

I think it is because my scripts are getting executed after my component's postconstruct method.

Can anyone please suggest any way to make it work.

So I tried autowiring DataSource and using it to read script in beforeAll as it is getting executed before postconstruct. But it's also getting injected after BeforeAll.

Upvotes: 0

Views: 330

Answers (1)

Oleg Šelajev
Oleg Šelajev

Reputation: 3800

How do you create the sqlContainer() thing?

My initial reaction would be that rather than rely on @Sql to initialize the data, I'd use the image native tools.

Most database images have support for init scripts from special directory, normally /docker-entrypoint-initdb.d/ like Postgres (search for: Initialization scripts)

PostgreSQLContainer<?> postgreSQLContainer =
    new PostgreSQLContainer<>("postgres:14-alpine")
.withCopyFileToContainer(MountableFile.forClasspathResource("schema.sql"), "/docker-entrypoint-initdb.d/");

Just be careful to create the schema before data. Alternatively, a database migration tooling is probably a good idea, since you really should probably use it in production anyway.

Upvotes: 0

Related Questions