added code examples for @SpringBootTest article

This commit is contained in:
Tom Hombergs
2019-02-24 06:55:20 +01:00
parent 93f8074914
commit 71fad7e002
36 changed files with 301 additions and 34 deletions

View File

@@ -1,11 +0,0 @@
<component name="libraryTable">
<library name="Gradle: org.projectlombok:lombok:1.16.20">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.16.20/ac76d9b956045631d1561a09289cbf472e077c01/lombok-1.16.20.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.16.20/69ebf81bb97bdb3c9581c171762bb4929cb5289c/lombok-1.16.20-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":spring-boot:spring-boot-testing" external.linked.project.path="$MODULE_DIR$/../../spring-boot/spring-boot-testing" external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="reflectoring.io" external.system.module.version="0.0.1-SNAPSHOT" type="JAVA_MODULE" version="4"> <module external.linked.project.id=":spring-boot:spring-boot-testing" external.linked.project.path="$MODULE_DIR$/../../spring-boot/spring-boot-testing" external.root.project.path="$MODULE_DIR$/../../tools/jacoco" external.system.id="GRADLE" external.system.module.group="reflectoring.io" external.system.module.version="0.0.1-SNAPSHOT" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$/../../spring-boot/spring-boot-testing"> <content url="file://$MODULE_DIR$/../../spring-boot/spring-boot-testing">

View File

@@ -2,6 +2,7 @@
## Blog Posts ## Blog Posts
* [Structuring and Testing Modules and Layers with Spring Boot](https://reflectoring.io/testing-verticals-and-layers-spring-boot/) * [Structuring and Testing Modules and Layers with Spring Boot](https://reflectoring.io/testing-verticals-and-layers-spring-boot/)
* [All You Need To Know About Unit Testing with Spring Boot](https://reflectoring.io/unit-testing-spring-boot/) * [Unit Testing with Spring Boot](https://reflectoring.io/unit-testing-spring-boot/)
* [All You Need To Know About Testing Web Controllers with Spring Boot](https://reflectoring.io/spring-boot-web-controller-test/) * [Testing Spring MVC Web Controllers with @WebMvcTest](https://reflectoring.io/spring-boot-web-controller-test/)
* [All You Need To Know About Testing JPA Queries with Spring Boot](https://reflectoring.io/spring-boot-data-jpa-test/) * [Testing JPA Queries with @DataJpaTest](https://reflectoring.io/spring-boot-data-jpa-test/)
* [Integration Tests with @SpringBoot](https://reflectoring.io/spring-boot-test/)

View File

@@ -0,0 +1,5 @@
spring.main.allow-bean-definition-overriding: true
spring.jpa.hibernate.ddl-auto: create-drop
spring.liquibase.enabled: false
spring.flyway.enabled: false
foo: bar

View File

@@ -0,0 +1,5 @@
spring.main.allow-bean-definition-overriding: true
spring.jpa.hibernate.ddl-auto: create-drop
spring.liquibase.enabled: false
spring.flyway.enabled: false
io.reflectoring.scheduling.enabled: false

View File

@@ -1,6 +1,6 @@
buildscript { buildscript {
ext { ext {
springBootVersion = '2.0.2.RELEASE' springBootVersion = '2.1.3.RELEASE'
} }
repositories { repositories {
mavenCentral() mavenCentral()
@@ -20,10 +20,10 @@ version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8 sourceCompatibility = 1.8
repositories { repositories {
jcenter()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa') compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web') compile('org.springframework.boot:spring-boot-starter-web')
@@ -34,6 +34,15 @@ dependencies {
compileOnly('org.projectlombok:lombok') compileOnly('org.projectlombok:lombok')
runtime('com.h2database:h2') runtime('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile 'org.junit.jupiter:junit-jupiter-engine:5.2.0' testCompile('org.junit.jupiter:junit-jupiter:5.4.0')
testCompile('org.junit.platform:junit-platform-launcher:1.4.0')
testCompile('org.mockito:mockito-junit-jupiter:2.23.0') testCompile('org.mockito:mockito-junit-jupiter:2.23.0')
testCompile('de.adesso:junit-insights:1.0.0')
annotationProcessor 'org.projectlombok:lombok:1.18.6'
}
test {
systemProperty 'de.adesso.junitinsights.enabled', 'true'
systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true'
useJUnitPlatform()
} }

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Tue Feb 06 12:27:20 CET 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip

View File

@@ -0,0 +1,14 @@
package io.reflectoring;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
@ConditionalOnProperty(
name = "io.reflectoring.scheduling.enabled",
havingValue = "true",
matchIfMissing = true)
public class SchedulingConfiguration {
}

View File

@@ -11,8 +11,15 @@ public class RegisterUseCase {
private final SaveUserPort saveUserPort; private final SaveUserPort saveUserPort;
private final SendMailPort sendMailPort;
public Long registerUser(User user, boolean sendWelcomeMail) { public Long registerUser(User user, boolean sendWelcomeMail) {
user.setRegistrationDate(LocalDateTime.now()); user.setRegistrationDate(LocalDateTime.now());
if(sendWelcomeMail){
sendMailPort.sendMail("Welcome!", "Thanks for registering.");
}
return saveUserPort.saveUser(user); return saveUserPort.saveUser(user);
} }

View File

@@ -0,0 +1,7 @@
package io.reflectoring.testing.domain;
public interface SendMailPort {
void sendMail(String subject, String text);
}

View File

@@ -0,0 +1,14 @@
package io.reflectoring.testing.mail;
import io.reflectoring.testing.domain.SendMailPort;
import org.springframework.stereotype.Component;
@Component
public class MailingAdapter implements SendMailPort {
@Override
public void sendMail(String subject, String text) {
// sending a mail...
}
}

View File

@@ -6,11 +6,14 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Component @Component
@RequiredArgsConstructor
public class PersistenceAdapter implements SaveUserPort { public class PersistenceAdapter implements SaveUserPort {
private final UserRepository userRepository; private final UserRepository userRepository;
public PersistenceAdapter(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override @Override
public Long saveUser(User user) { public Long saveUser(User user) {
UserEntity userEntity = new UserEntity( UserEntity userEntity = new UserEntity(
@@ -19,4 +22,9 @@ public class PersistenceAdapter implements SaveUserPort {
UserEntity savedUserEntity = userRepository.save(userEntity); UserEntity savedUserEntity = userRepository.save(userEntity);
return savedUserEntity.getId(); return savedUserEntity.getId();
} }
public User loadUser(Long id) {
UserEntity userEntity = userRepository.findById(id).get();
return new User(userEntity.getId(), userEntity.getName(), userEntity.getEmail(), userEntity.getRegistrationDate());
}
} }

View File

@@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
interface UserRepository extends CrudRepository<UserEntity, Long> { public interface UserRepository extends CrudRepository<UserEntity, Long> {
UserEntity findByName(String name); UserEntity findByName(String name);

View File

@@ -6,7 +6,11 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
@SpringBootTest @SpringBootTest(properties = {
"spring.jpa.hibernate.ddl-auto=create-drop",
"spring.liquibase.enabled=false",
"spring.flyway.enabled=false"
})
class ApplicationTests { class ApplicationTests {
@Test @Test

View File

@@ -10,7 +10,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = BookingConfiguration.class) @SpringBootTest(classes = BookingConfiguration.class)
class BookingConfigurationTest { class BookingConfigurationTest {

View File

@@ -14,7 +14,6 @@ import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
@SpringBootTest @SpringBootTest
class BookingIntegrationTest { class BookingIntegrationTest {

View File

@@ -21,7 +21,6 @@ import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = BookingController.class) @WebMvcTest(controllers = BookingController.class)
class BookingControllerTest { class BookingControllerTest {

View File

@@ -5,7 +5,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = CustomerConfiguration.class) @SpringBootTest(classes = CustomerConfiguration.class)
class CustomerConfigurationTest { class CustomerConfigurationTest {

View File

@@ -12,7 +12,6 @@ import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@DataJpaTest @DataJpaTest
class CustomerRepositoryTest { class CustomerRepositoryTest {

View File

@@ -0,0 +1,47 @@
package io.reflectoring.testing;
import java.time.LocalDateTime;
import io.reflectoring.testing.domain.RegisterUseCase;
import io.reflectoring.testing.domain.User;
import io.reflectoring.testing.persistence.PersistenceAdapter;
import io.reflectoring.testing.persistence.UserEntity;
import io.reflectoring.testing.persistence.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@SpringBootTest
class MockBeanTest {
@MockBean
private UserRepository userRepository;
@Autowired
private RegisterUseCase registerUseCase;
@Test
void testRegister(){
// given
User user = new User("Zaphod", "zaphod@galaxy.net");
boolean sendWelcomeMail = true;
// when
when(userRepository.save(any(UserEntity.class))).thenReturn(userEntity(1L));
Long userId = registerUseCase.registerUser(user, sendWelcomeMail);
// then
assertThat(userId).isEqualTo(1L);
}
private UserEntity userEntity(Long id){
return new UserEntity(id, "Zaphod", "zaphod@galaxy.net", LocalDateTime.now());
}
}

View File

@@ -0,0 +1,48 @@
package io.reflectoring.testing;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.reflectoring.testing.persistence.PersistenceAdapter;
import io.reflectoring.testing.persistence.UserEntity;
import io.reflectoring.testing.persistence.UserRepository;
import io.reflectoring.testing.web.UserResource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest(properties = {
"spring.jpa.hibernate.ddl-auto=create-drop",
"spring.liquibase.enabled=false",
"spring.flyway.enabled=false"
})
@AutoConfigureMockMvc
public class RegisterUseCaseIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private UserRepository userRepository;
@Test
void registrationWorksThroughAllLayers() throws Exception {
UserResource user = new UserResource("Zaphod", "zaphod@galaxy.net");
mockMvc.perform(post("/forums/{forumId}/register", 42L)
.contentType("application/json")
.param("sendWelcomeMail", "true")
.content(objectMapper.writeValueAsString(user)))
.andExpect(status().isOk());
UserEntity userEntity = userRepository.findByName("Zaphod");
assertThat(userEntity.getEmail()).isEqualTo("zaphod@galaxy.net");
}
}

View File

@@ -2,6 +2,7 @@ package io.reflectoring.testing;
import io.reflectoring.testing.domain.RegisterUseCase; import io.reflectoring.testing.domain.RegisterUseCase;
import io.reflectoring.testing.domain.SaveUserPort; import io.reflectoring.testing.domain.SaveUserPort;
import io.reflectoring.testing.domain.SendMailPort;
import io.reflectoring.testing.domain.User; import io.reflectoring.testing.domain.User;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -19,17 +20,20 @@ class RegisterUseCaseTest {
@Mock @Mock
private SaveUserPort saveUserPort; private SaveUserPort saveUserPort;
@Mock
private SendMailPort sendMailPort;
private RegisterUseCase registerUseCase; private RegisterUseCase registerUseCase;
@BeforeEach @BeforeEach
void initUseCase() { void initUseCase() {
registerUseCase = new RegisterUseCase(saveUserPort); registerUseCase = new RegisterUseCase(saveUserPort, sendMailPort);
} }
@Test @Test
void savedUserHasRegistrationDate() { void savedUserHasRegistrationDate() {
User user = new User("zaphod", "zaphod@mail.com"); User user = new User("zaphod", "zaphod@mail.com");
when(saveUserPort.saveUser(any(User.class))).then(returnsFirstArg()); when(saveUserPort.saveUser(any(User.class))).thenReturn(42L);
Long userId = registerUseCase.registerUser(user, false); Long userId = registerUseCase.registerUser(user, false);
assertThat(userId).isNotNull(); assertThat(userId).isNotNull();
} }

View File

@@ -0,0 +1,21 @@
package io.reflectoring.testing;
import io.reflectoring.SchedulingConfiguration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest(properties = "io.reflectoring.scheduling.enabled=false")
class SchedulingTest {
@Autowired(required = false)
private SchedulingConfiguration schedulingConfiguration;
@Test
void test() {
assertThat(schedulingConfiguration).isNull();
}
}

View File

@@ -0,0 +1,21 @@
package io.reflectoring.testing;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import other.namespace.Foo;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest
@Import(other.namespace.Foo.class)
class SpringBootImportTest {
@Autowired
Foo foo;
@Test
void test() {
assertThat(foo).isNotNull();
}
}

View File

@@ -0,0 +1,20 @@
package io.reflectoring.testing;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest
@ActiveProfiles("test")
class SpringBootProfileTest {
@Value("${foo}")
String foo;
@Test
void test(){
assertThat(foo).isEqualTo("bar");
}
}

View File

@@ -0,0 +1,18 @@
package io.reflectoring.testing;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(properties = "foo=bar")
class SpringBootPropertiesTest {
@Value("${foo}")
String foo;
@Test
void test(){
assertThat(foo).isEqualTo("bar");
}
}

View File

@@ -0,0 +1,20 @@
package io.reflectoring.testing;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest
@TestPropertySource(locations = "/foo.properties")
class SpringBootPropertySourceTest {
@Value("${foo}")
String foo;
@Test
void test(){
assertThat(foo).isEqualTo("bar");
}
}

View File

@@ -7,7 +7,6 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@DataJpaTest @DataJpaTest
@TestPropertySource(properties = { @TestPropertySource(properties = {
"spring.jpa.hibernate.ddl-auto=validate", "spring.jpa.hibernate.ddl-auto=validate",

View File

@@ -12,7 +12,6 @@ import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
@ExtendWith(SpringExtension.class)
@DataJpaTest @DataJpaTest
@TestPropertySource(properties = { @TestPropertySource(properties = {
"spring.jpa.hibernate.ddl-auto=create-drop", "spring.jpa.hibernate.ddl-auto=create-drop",

View File

@@ -6,7 +6,6 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@DataJpaTest @DataJpaTest
@TestPropertySource(properties = { @TestPropertySource(properties = {
"spring.jpa.hibernate.ddl-auto=validate", "spring.jpa.hibernate.ddl-auto=validate",

View File

@@ -15,7 +15,6 @@ import org.springframework.test.context.support.DependencyInjectionTestExecution
import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import static org.assertj.core.api.Java6Assertions.*; import static org.assertj.core.api.Java6Assertions.*;
@ExtendWith(SpringExtension.class)
@DataJpaTest @DataJpaTest
@TestPropertySource(properties = { @TestPropertySource(properties = {
"spring.jpa.hibernate.ddl-auto=create-drop", "spring.jpa.hibernate.ddl-auto=create-drop",

View File

@@ -9,7 +9,6 @@ import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Java6Assertions.*; import static org.assertj.core.api.Java6Assertions.*;
@ExtendWith(SpringExtension.class)
@DataJpaTest @DataJpaTest
@TestPropertySource(properties = { @TestPropertySource(properties = {
"spring.jpa.hibernate.ddl-auto=create-drop", "spring.jpa.hibernate.ddl-auto=create-drop",

View File

@@ -18,7 +18,6 @@ import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = RegisterRestController.class) @WebMvcTest(controllers = RegisterRestController.class)
class RegisterRestControllerTest { class RegisterRestControllerTest {
@@ -37,6 +36,8 @@ class RegisterRestControllerTest {
UserResource user = new UserResource("Zaphod", "zaphod@galaxy.net"); UserResource user = new UserResource("Zaphod", "zaphod@galaxy.net");
mockMvc.perform(post("/forums/42/register") mockMvc.perform(post("/forums/42/register")
.param("sendWelcomeMail", "true")
.content(objectMapper.writeValueAsString(user))
.contentType("application/json")) .contentType("application/json"))
.andExpect(status().isOk()); .andExpect(status().isOk());

View File

@@ -0,0 +1,7 @@
package other.namespace;
import org.springframework.stereotype.Component;
@Component
public class Foo {
}

View File

@@ -0,0 +1 @@
foo=bar