Spring Boot Test - SGajre/Tutorial GitHub Wiki
Spring boot 1.3 version:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=MyApp.class, loader=SpringApplicationContextLoader.class)` public class MyTest { // .. }
OR
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(MyApp.class) public class MyTest { // ... }
Or
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(MyApp.class) @IntegrationTest public class MyTest { // ... }
Spring boot Test: 1.4 version
spring-boot-test = contains core items, and spring-boot-test-autoconfigure = supports auto-configuration for tests. spring-boot-starter-test = ‘Starter’ which imports both Spring Boot test modules as well has JUnit, AssertJ, Hamcrest and a number of other useful libraries.
@SpringBootTest @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
- Alternative to spring-test @ContextConfiguration annotation. @RunWith(SpringRunner.class) renamed from @RunWith(SpringJUnit4ClassRunner.class)
Old Spring Test framework
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:/app-context-test.xml" ) @TestExecutionListeners({DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class})
-
If you want to customize the primary configuration, you can use a nested @TestConfiguration class.
-
@TestComponent and @TestConfiguration are only needed on top level classes.
-
If you define @Configuration or @Component as inner-classes within a test (any class that has @Test methods or @RunWith), they will be automatically filtered.
example: @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class RandomPortExampleTests {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void exampleTest() {
String body = this.restTemplate.getForObject("/", String.class);
assertThat(body).isEqualTo("Hello World");
}
}
with Mocitko:
@RunWith(SpringRunner.class) @SpringBootTest public class MyTests {
@MockBean
private RemoteService remoteService;
@Autowired
private Reverser reverser;
@Test
public void exampleTest() {
// RemoteService has been injected into the reverser bean
given(this.remoteService.someCall()).willReturn("mock");
String reverse = reverser.reverseSomeCall();
assertThat(reverse).isEqualTo("kcom");
}
}
- Additionally you can also use @SpyBean to wrap any existing bean with a Mockito spy.
---------------------------------------
Auto-configured JSON tests
---------------------------------------
@RunWith(SpringRunner.class)
@JsonTest
public class MyJsonTests {
@Autowired
private JacksonTester json;
@Test
public void testSerialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a .json file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
.isEqualTo("Honda");
}
@Test
public void testDeserialize() throws Exception {
String content = "{"make":"Ford","model":"Focus"}";
assertThat(this.json.parse(content))
.isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}
}
----------------------------------------
Auto-configured Spring MVC tests
----------------------------------------
@RunWith(SpringRunner.class) @WebMvcTest(UserVehicleController.class) public class MyControllerTests { @Autowired private MockMvc mvc; @MockBean private UserVehicleService userVehicleService; @Test public void testExample() throws Exception { given(this.userVehicleService.getVehicleDetails("sboot")) .willReturn(new VehicleDetails("Honda", "Civic")); this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)) .andExpect(status().isOk()).andExpect(content().string("Honda Civic")); } }
- If you need to configure elements of the auto-configuration (for example when servlet filters should be applied) you can use attributes in the @AutoConfigureMockMvc annotation.
----------------------------------------------
Here is an example that uses HtmlUnit:
-----------------------------------------------
@RunWith(SpringRunner.class) @WebMvcTest(UserVehicleController.class) public class MyHtmlUnitTests { @Autowired private WebClient webClient; @MockBean private UserVehicleService userVehicleService; @Test public void testExample() throws Exception { given(this.userVehicleService.getVehicleDetails("sboot")) .willReturn(new VehicleDetails("Honda", "Civic")); HtmlPage page = this.webClient.getPage("/sboot/vehicle.html"); assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic"); } }
---------------------------------------------------
Auto-configured Data JPA tests
---------------------------------------------------
@RunWith(SpringRunner.class) @DataJpaTest @Transactional(propagation = Propagation.NOT_SUPPORTED) public class ExampleNonTransactionalTests {
}
- Data JPA tests may also inject a TestEntityManager bean which provides an alternative to the standard JPA EntityManager specifically designed for tests.
@RunWith(SpringRunner.class) @DataJpaTest public class ExampleRepositoryTests { @Autowired private TestEntityManager entityManager;
@Autowired
private UserRepository repository;
@Test
public void testExample() throws Exception {
this.entityManager.persist(new User("sboot", "1234"));
User user = this.repository.findByUsername("sboot");
assertThat(user.getUsername()).isEqualTo("sboot");
assertThat(user.getVin()).isEqualTo("1234");
}
- If you prefer to run tests against a real database you can use the @AutoConfigureTestDatabase annotation:
@RunWith(SpringRunner.class) @DataJpaTest @AutoConfigureTestDatabase(replace=Replace.NONE) public class ExampleRepositoryTests { // ... }
-----------------------------------------------------
Auto-configured JDBC tests
-----------------------------------------------------
- @JdbcTest is similar to @DataJpaTest but for pure jdbc-related tests.
- By default it will also configure an in-memory embedded database and a JdbcTemplate. Regular @Component beans will not be loaded into the ApplicationContext.
@RunWith(SpringRunner.class) @JdbcTest @Transactional(propagation = Propagation.NOT_SUPPORTED) public class ExampleNonTransactionalTests {
}
- If you prefer your test to run against a real database, you can use the @AutoConfigureTestDatabase annotation the same way as for DataJpaTest.
Auto-configured Data MongoDB tests
- @DataMongoTest can be used if you want to test MongoDB applications. By default, it will configure an in-memory embedded MongoDB (if available), configure a MongoTemplate, scan for @Document classes and configure Spring Data MongoDB repositories.
- Regular @Component beans will not be loaded into the ApplicationContext:
@RunWith(SpringRunner.class)
@DataMongoTest public class ExampleDataMongoTests {
@Autowired private MongoTemplate mongoTemplate; // }
- you prefer to run tests against a real MongoDB server you should exclude the embedded mongodb auto-configuration:
@RunWith(SpringRunner.class)
@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class) public class ExampleDataMongoNonEmbeddedTests {
}
-----------------------------------------------
Auto-configured REST clients
-----------------------------------------------
- By default it will auto-configure Jackson and GSON support, configure a RestTemplateBuilder and add support for MockRestServiceServer.
- The specific beans that you want to test should be specified using value or components attribute of @RestClientTest:
@RunWith(SpringRunner.class)
@RestClientTest(RemoteVehicleDetailsService.class)`
public class ExampleRestClientTest {
@Autowired
private RemoteVehicleDetailsService service;
@Autowired
private MockRestServiceServer server;`
@Test`
public void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails()throws Exception {
this.server.expect(requestTo("/greet/details"))
`.andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));`
String greeting = this.service.callRestService();
assertThat(greeting).isEqualTo("hello");
}
}
Auto-configured Spring REST Docs tests
Test utilities
ConfigFileApplicationContextInitializer --
- It is an ApplicationContextInitializer that can apply to your tests to load Spring Boot application.properties
- You can use this when you don’t need the full features provided by @SpringBootTest.
@ContextConfiguration(classes = Config.class, initializers = ConfigFileApplicationContextInitializer.class)
- EnvironmentTestUtils -- this allows you to quickly add properties to a ConfigurableEnvironment or ConfigurableApplicationContext (Key=value)
EnvironmentTestUtils.addEnvironment(env, "org=Spring", "name=Boot");
OutputCapture - is a JUnit Rule that you can use to capture System.out and System.err output
public class MyTest {
@Rule
public OutputCapture capture = new OutputCapture();
@Test
public void testName() throws Exception {
System.out.println("Hello World!");
assertThat(capture.toString(), containsString("World"));
}
}
TestRestTemplate --
public class MyTest {
private TestRestTemplate template = new TestRestTemplate();
@Test
public void testRequest() throws Exception {
HttpHeaders headers = template.getForEntity("http://myhost.com", String.class).getHeaders();
assertThat(headers.getLocation().toString(), containsString("myotherhost"));
}
}
RestTemplateBuilder --
-
If you are using the @SpringBootTest annotation with WebEnvironment.RANDOM_PORT or WebEnvironment.DEFINED_PORT, you can just inject a fully configured TestRestTemplate and start using it. If necessary, additional customizations can be applied via the RestTemplateBuilder bean: @RunWith(SpringRunner.class) @SpringBootTest public class MyTest {
@Autowired private TestRestTemplate template;
@Test public void testRequest() throws Exception { HttpHeaders headers = template.getForEntity("http://myhost.com", String.class).getHeaders(); assertThat(headers.getLocation().toString(), containsString("myotherhost")); }
@TestConfiguration static class Config {
@Bean public RestTemplateBuilder restTemplateBuilder() { return new RestTemplateBuilder() .additionalMessageConverters(...) .customizers(...); }} }