Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions testing-modules/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<module>spring-mockito</module>
<module>spring-testing-2</module>
<module>spring-testing-3</module>
<module>spring-testing-4</module>
<module>spring-testing</module>
<module>testing-assertions</module>
<module>test-containers</module>
Expand Down
93 changes: 93 additions & 0 deletions testing-modules/spring-testing-4/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-testing-4</artifactId>
<version>0.1-SNAPSHOT</version>
<name>spring-testing-4</name>

<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-3</relativePath>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>

<!-- test -->
<dependency>
<groupId>com.github.seregamorph</groupId>
<artifactId>spring-test-smart-context</artifactId>
<version>0.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<properties>
<java.version>17</java.version>
<spring-boot.repackage.skip>true</spring-boot.repackage.skip>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<!-- Include test classes with names matching the pattern -->
<excludes>
<exclude>*IntTest.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>*IntTest.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.java.baeldung.spring.test;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/articles")
public class ArticlesController {

@GetMapping("/{id}")
public String get(@PathVariable("id") long id) {
return "Content " + id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.java.baeldung.spring.test;

import com.github.seregamorph.testsmartcontext.SmartDirtiesContextTestExecutionListener;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit.jupiter.SpringExtension;

// Avoid putting @DirtiesContext on the integration test super class
// @DirtiesContext
// Use SmartDirtiesContextTestExecutionListener instead
@ContextConfiguration(classes = {
SampleBeanTestConfiguration.class
})
@ActiveProfiles("test")
@TestExecutionListeners(listeners = {
SmartDirtiesContextTestExecutionListener.class,
}, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
@ExtendWith(SpringExtension.class)
public abstract class AbstractIntegrationTest {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.java.baeldung.spring.test;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration
@ContextConfiguration(classes = {
PostgresTestConfiguration.class,
DataSourceTestConfiguration.class,
ArticlesController.class
})
@TestPropertySource(properties = {
"parameter = value"
})
public abstract class AbstractWebIntTest extends AbstractIntegrationTest {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.java.baeldung.spring.test;

import com.github.seregamorph.testsmartcontext.jdbc.LateInitDataSource;
import com.zaxxer.hikari.HikariDataSource;
import org.postgresql.Driver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.testcontainers.containers.PostgreSQLContainer;

import javax.sql.DataSource;

@Configuration
public class DataSourceTestConfiguration {

private static final Logger logger = LoggerFactory.getLogger(DataSourceTestConfiguration.class);

// Avoid creating TestContainer objects which are not spring-managed beans
// @Bean
// public DataSource dataSource() {
// // not a manageable bean!
// var container = new PostgreSQLContainer("postgres:9.6");
// container.start();
// return createDataSource("main", container);
// }

@Bean
public DataSource dataSource(PostgreSQLContainer<?> postgres) {
return createDataSource("main", postgres);
}

private static DataSource createDataSource(String name, PostgreSQLContainer<?> postgres) {
// todo schema migrations, test data insertion, etc.
if (postgres.isRunning()) {
// already running - create direct dataSource
logger.info("Eagerly initializing pool {}", name);
return createHikariDataSourceForContainer(name, postgres);
} else {
// initialize lazily on first getConnection
logger.info("Pool {} will be initialized lazily", name);
return new LateInitDataSource(name, () -> {
logger.info("Starting container for pool {}", name);
postgres.start();
return createHikariDataSourceForContainer(name, postgres);
});
}
}

private static HikariDataSource createHikariDataSourceForContainer(String name, PostgreSQLContainer<?> container) {
var hikariDataSource = new HikariDataSource();
hikariDataSource.setUsername(container.getUsername());
hikariDataSource.setPassword(container.getPassword());
hikariDataSource.setMinimumIdle(0);
hikariDataSource.setMaximumPoolSize(50);
hikariDataSource.setIdleTimeout(10000);
hikariDataSource.setConnectionTimeout(10000);
hikariDataSource.setAutoCommit(true);
hikariDataSource.setPoolName(name);
hikariDataSource.setDriverClassName(Driver.class.getName());
hikariDataSource.setJdbcUrl(container.getJdbcUrl());
return hikariDataSource;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.java.baeldung.spring.test;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;

@Configuration
public class PostgresTestConfiguration {

private static PostgreSQLContainer<?> postgres;

// override destroy method to empty to avoid closing docker container
// bean on closing spring context
@Bean(destroyMethod = "")
public PostgreSQLContainer<?> postgresContainer() {
synchronized (PostgresTestConfiguration.class) {
if (postgres == null) {
postgres = new PostgreSQLContainer<>(DockerImageName.parse("postgres:14")
.asCompatibleSubstituteFor("postgres"));
}
return postgres;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.java.baeldung.spring.test;

public class SampleBean {

public String getValue() {
return "default";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.java.baeldung.spring.test;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Import;

@Import({
SampleBean.class,
SampleService.class
})
@TestConfiguration
public class SampleBeanTestConfiguration {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.java.baeldung.spring.test;

import jakarta.annotation.PreDestroy;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class SampleService {

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(16);

private final SampleBean sampleBean;

public SampleService(SampleBean sampleBean) {
this.sampleBean = sampleBean;
}

public void scheduleNow(Runnable command, long periodSeconds) {
scheduler.scheduleAtFixedRate(command, 0L, periodSeconds, TimeUnit.SECONDS);
}

public String getValue() {
return sampleBean.getValue();
}

// to avoid thread leakage in test execution
@PreDestroy
public void shutdown() {
scheduler.shutdown();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.java.baeldung.spring.test;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Test1IntTest extends AbstractIntegrationTest {

@Autowired
private SampleBean rootBean;

@Test
public void test() {
System.out.println("Test1IT.test " + rootBean);
assertEquals("default", rootBean.getValue());
}

@Nested
public class NestedIT {

@Autowired
private SampleBean nestedBean;

@Test
public void nested() {
System.out.println("Test1IT.NestedTest.test " + nestedBean);
}

@Nested
public class DeeplyNestedIT {

@Autowired
private SampleService sampleService;

@Test
public void deeplyNested() {
assertEquals("default", sampleService.getValue());
System.out.println("Test1IT.NestedTest.DeeplyNestedTest.deeplyNested " + sampleService);
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.java.baeldung.spring.test;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Test2IntTest extends AbstractIntegrationTest {

@Autowired
private SampleBean rootBean;

@Test
public void test() {
System.out.println("Test2IT.test " + rootBean);
assertEquals("default", rootBean.getValue());
}
}
Loading