-
Notifications
You must be signed in to change notification settings - Fork 26
Add TestContainers sample for Doma Spring Boot #310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
2a0f96f
448f356
5198bb1
1e42f72
06610a1
45661c4
87b5535
237ea2d
487094d
2a5fa14
ccf7bfc
ccbf51f
cf62c8e
5f6bdc4
5f5aa9a
37dc226
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,9 +15,18 @@ To run this sample, you need: | |
| ./mvnw clean test | ||
| ``` | ||
|
|
||
| ### 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 | ||
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,22 +14,22 @@ | |
| @RequestMapping("/") | ||
|
||
| 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 |
|---|---|---|
|
|
@@ -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 | ||
|
||
| class ApplicationTest { | ||
| @Autowired | ||
| private TestRestTemplate restTemplate; | ||
| private final ParameterizedTypeReference<List<Message>> typedReference = new ParameterizedTypeReference<List<Message>>() { | ||
| }; | ||
| @LocalServerPort | ||
| private int port; | ||
| @Autowired | ||
| private TestRestTemplate restTemplate; | ||
|
||
| private final ParameterizedTypeReference<List<Message>> typedReference = new ParameterizedTypeReference<List<Message>>() { | ||
|
||
| }; | ||
| @LocalServerPort | ||
| private int port; | ||
|
|
||
| @Container | ||
| static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15"); | ||
|
|
||
| @DynamicPropertySource | ||
|
||
| 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 { | ||
|
||
|
|
||
| @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 | ||
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add maven wrapper