Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

Add TestContainers sample for Doma Spring Boot

This PR adds a new sample project that demonstrates how to use TestContainers with Doma Spring Boot.

Features

  • PostgreSQL container for testing
  • Spring Boot TestContainers integration
  • Similar structure to the simple sample
  • Demonstrates CRUD operations with Doma against a real PostgreSQL database

Fixes #290

Link to Devin run: https://app.devin.ai/sessions/50e457610bac4eae8a933380520d72b8
Requested by: [email protected]

@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@making
Copy link
Member

making commented May 19, 2025

@devin-ai-integration

This is not expected work requested in #290

Here is the document for Testcontainers support in Spring Boot.
https://docs.spring.io/spring-boot/reference/features/dev-services.html#features.dev-services.testcontainers

You should create a project from Spring Initializr with "Testcontainers" dependency included.

@making making self-assigned this May 19, 2025
Copy link
Member

@making making left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, create a project with Spring Initializr using maybe curl and leverage the generated files.

import org.testcontainers.utility.DockerImageName;

@TestConfiguration(proxyBeanMethods = false)
public class TestContainersConfig {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a project with Spring Initializr.
And use TestcontainersConfiguration class included in the generated project.

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = TestcontainersConfiguration.class)
@ActiveProfiles("test")
@Testcontainers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a project with Spring Initializr.
And import TestcontainersConfiguration class included in the generated project instead of @Testcontainers and @Container.

@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");

@DynamicPropertySource
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DynamicPropertySource is no longer needed as JdbcConnectionDetails is provided via Testconatiners support.

<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- TestContainers dependencies -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestContainers dependencies are managed by Spring Boot

<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- H2 for local development -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to Testcontainers support. PostgreSQL can be used for local development as well.
H2 is no longer needed in this project.

@Import(TestcontainersConfiguration.class)
class ApplicationTest {
@Autowired
private TestRestTemplate restTemplate;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modernize the test code by using RestClient instead of TestRestTemplate.

    RestClient restClient;

    @BeforeEach
    void setUp(@Autowired RestClient.Builder restClientBuilder) {
        this.restClient = restClientBuilder.defaultStatusHandler(__ -> true, (req, res) -> {
        }).build();
    }


# Doma configuration
doma.dialect=H2
doma.dialect=POSTGRES
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doma.dialect should be automatically detected via JdbcConnectionDetails

@BeforeEach
void setUp(@Autowired RestClient.Builder restClientBuilder) {
this.restClient = restClientBuilder.defaultStatusHandler(__ -> true, (req, res) -> {
}).build();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use .baseUrl("http://localhost:" + port) to build the RestClient and use .uri("/?text={text}", "hello") for each test method

.uri(UriComponentsBuilder.fromUriString("http://localhost").port(port)
.queryParam("page", "1").queryParam("size", "1").build()
.toUri())
.uri("/?page={page}&size={size}", "1", "1")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

page and size should be int


# Doma configuration
doma.naming=SNAKE_LOWER_CASE
logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DataSourceTransactionManager is old. Use JdbcTransactionManager instead.

logging.level.org.springframework.jdbc.support.JdbcTransactionManager=DEBUG

@Import(TestcontainersConfiguration.class)
class ApplicationTest {
private RestClient restClient;
private final ParameterizedTypeReference<List<Message>> typedReference = new ParameterizedTypeReference<List<Message>>() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicit type argument List<Message> can be replaced with <>

### Build and Run Tests

```bash
./mvnw clean test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add maven wrapper

@@ -0,0 +1,2 @@
# Test configuration for PostgreSQL
spring.sql.init.mode=always
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant file


### Build and Run Tests

This project uses the Maven Wrapper, so you don't need to install Maven separately.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, no. Include .mvn, mvnw and mvnw.cmd in this repo


# Doma configuration
doma.naming=SNAKE_LOWER_CASE
logging.level.org.springframework.jdbc.support.JdbcTransactionManager=DEBUG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add logging.level.org.seasar.doma.jdbc=DEBUG to show SQL logs

@@ -0,0 +1,6 @@
# Development configuration using TestContainers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is useless

<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

junit is managed by Spring Boot

import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use path attriubte

…explicit JUnit dependency, use path attribute in RequestMapping

Co-Authored-By: [email protected] <[email protected]>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit is managed by Spring Boot -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this comment

<scope>test</scope>
</dependency>
<!-- JUnit is managed by Spring Boot -->
<!-- Spring Boot manages TestContainers dependencies -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this comment as well

- Spring Boot's native TestContainers integration with `@ServiceConnection`
- Using TestContainers at development time with `SpringApplication.from()`
- Running Doma queries against a real PostgreSQL database in tests
- Configuration for both development (H2) and test (PostgreSQL) environments
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

H2 is not used

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- PostgreSQL Driver -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this comment

Copy link
Member

@making making left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Good Job!

@making making merged commit edc57c5 into master May 19, 2025
6 checks passed
@making making deleted the devin/1747645488-add-testcontainers-sample branch May 19, 2025 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add sample using TestContainers

2 participants