Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
2a0f96f
Add TestContainers sample for Doma Spring Boot (Fixes #290)
devin-ai-integration[bot] May 19, 2025
448f356
Revise TestContainers sample to use Spring Boot's native TestContaine…
devin-ai-integration[bot] May 19, 2025
5198bb1
Fix code formatting issues
devin-ai-integration[bot] May 19, 2025
1e42f72
Update TestContainers sample to use Spring Initializr generated approach
devin-ai-integration[bot] May 19, 2025
06610a1
Remove old TestContainersConfig.java file
devin-ai-integration[bot] May 19, 2025
45661c4
Update TestContainers sample based on feedback: use RestClient, remov…
devin-ai-integration[bot] May 19, 2025
87b5535
Update TestContainers sample based on feedback: remove explicit diale…
devin-ai-integration[bot] May 19, 2025
237ea2d
Change page and size parameters to integers in ApplicationTest
devin-ai-integration[bot] May 19, 2025
487094d
Update transaction manager logging to use JdbcTransactionManager
devin-ai-integration[bot] May 19, 2025
2a5fa14
Use diamond operator for ParameterizedTypeReference
devin-ai-integration[bot] May 19, 2025
ccf7bfc
Add Maven wrapper info to README and remove redundant application-tes…
devin-ai-integration[bot] May 19, 2025
ccbf51f
Add Maven wrapper files to TestContainers sample
devin-ai-integration[bot] May 19, 2025
cf62c8e
Address PR comments: add SQL logging, remove useless comment, remove …
devin-ai-integration[bot] May 19, 2025
5f6bdc4
Remove JUnit comment from pom.xml
devin-ai-integration[bot] May 19, 2025
5f5aa9a
Remove TestContainers comment from pom.xml
devin-ai-integration[bot] May 19, 2025
37dc226
Remove PostgreSQL Driver comment and fix README.md to remove H2 refer…
devin-ai-integration[bot] May 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,18 @@ To run this sample, you need:
./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

```

### Run with TestContainers

```bash
./mvnw spring-boot:test-run
```

This will start the application with a PostgreSQL container.

## Features Demonstrated

- Using TestContainers to start a PostgreSQL database for tests
- Integration with Spring Boot's test support for TestContainers
- 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

Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@
<version>1.19.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
<version>${spring-boot.version}</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
@SpringBootApplication
public class Application {

@SuppressWarnings("resource")
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@SuppressWarnings("resource")
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
@Entity
@Table(name = "messages")
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer id;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer id;

public String text;
public String text;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@
@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

public class MessageController {

private final MessageDao messageDao;
private final MessageDao messageDao;

public MessageController(MessageDao messageDao) {
this.messageDao = messageDao;
}
public MessageController(MessageDao messageDao) {
this.messageDao = messageDao;
}

@GetMapping
List<Message> list(@PageableDefault Pageable pageable) {
return messageDao.selectAll(Pageables.toSelectOptions(pageable));
}
@GetMapping
List<Message> list(@PageableDefault Pageable pageable) {
return messageDao.selectAll(Pageables.toSelectOptions(pageable));
}

@GetMapping(params = "text")
Message add(@RequestParam String text) {
Message message = new Message();
message.text = text;
messageDao.insert(message);
return message;
}
@GetMapping(params = "text")
Message add(@RequestParam String text) {
Message message = new Message();
message.text = text;
messageDao.insert(message);
return message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
@ConfigAutowireable
@Transactional
public interface MessageDao {
@Select
List<Message> selectAll(SelectOptions options);
@Select
List<Message> selectAll(SelectOptions options);

@Insert
int insert(Message message);
@Insert
int insert(Message message);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,72 @@
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.web.util.UriComponentsBuilder;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@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.

class ApplicationTest {
@Autowired
private TestRestTemplate restTemplate;
private final ParameterizedTypeReference<List<Message>> typedReference = new ParameterizedTypeReference<List<Message>>() {
};
@LocalServerPort
private int port;
@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();
    }

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

};
@LocalServerPort
private int port;

@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.

static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
registry.add("doma.dialect", () -> "POSTGRES");
}

@Test
void testWithTestContainers() {
Message message1 = restTemplate.getForObject(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.queryParam("text", "hello").build().toUri(),
Message.class);
assertEquals(1, message1.id);
assertEquals("hello", message1.text);
Message message2 = restTemplate.getForObject(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.queryParam("text", "world").build().toUri(),
Message.class);
assertEquals(2, message2.id);
assertEquals("world", message2.text);
@Test
void testWithTestContainers() {
Message message1 = restTemplate.getForObject(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.queryParam("text", "hello").build().toUri(),
Message.class);
assertEquals(1, message1.id);
assertEquals("hello", message1.text);
Message message2 = restTemplate.getForObject(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.queryParam("text", "world").build().toUri(),
Message.class);
assertEquals(2, message2.id);
assertEquals("world", message2.text);

{
List<Message> messages = restTemplate.exchange(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.build().toUri(),
HttpMethod.GET, HttpEntity.EMPTY,
typedReference).getBody();
assertEquals(2, messages.size());
assertEquals(message1.id, messages.get(0).id);
assertEquals(message1.text, messages.get(0).text);
assertEquals(message2.id, messages.get(1).id);
assertEquals(message2.text, messages.get(1).text);
}
{
List<Message> messages = restTemplate.exchange(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.build().toUri(),
HttpMethod.GET, HttpEntity.EMPTY,
typedReference).getBody();
assertEquals(2, messages.size());
assertEquals(message1.id, messages.get(0).id);
assertEquals(message1.text, messages.get(0).text);
assertEquals(message2.id, messages.get(1).id);
assertEquals(message2.text, messages.get(1).text);
}

{
List<Message> messages = restTemplate.exchange(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.queryParam("page", "1").queryParam("size", "1").build()
.toUri(),
HttpMethod.GET, HttpEntity.EMPTY, typedReference)
.getBody();
assertEquals(1, messages.size());
assertEquals(message2.id, messages.get(0).id);
assertEquals(message2.text, messages.get(0).text);
}
}
{
List<Message> messages = restTemplate.exchange(
UriComponentsBuilder.fromUriString("http://localhost").port(port)
.queryParam("page", "1").queryParam("size", "1").build()
.toUri(),
HttpMethod.GET, HttpEntity.EMPTY, typedReference)
.getBody();
assertEquals(1, messages.size());
assertEquals(message2.id, messages.get(0).id);
assertEquals(message2.text, messages.get(0).text);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.seasar.doma.boot.sample;

import org.springframework.boot.SpringApplication;

public class TestApplication {

public static void main(String[] args) {
SpringApplication.from(Application::main)
.with(TestContainersConfig.class)
.run(args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.seasar.doma.boot.sample;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.PostgreSQLContainer;
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.


@Bean
@ServiceConnection
public PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>(DockerImageName.parse("postgres:15"))
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
# Test configuration for PostgreSQL
spring.datasource.driver-class-name=org.postgresql.Driver
doma.dialect=POSTGRES
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

Loading