Spring Boot Test
This Spring Boot Test example is to test the Spring Boot application created in this story.
In the project created in the aforementioned story, modify the Bazel WORKSPACE to add the test dependencies:
......maven_install(
artifacts = [......# test
"org.springframework:spring-test:5.2.13.RELEASE",
"org.springframework.boot:spring-boot-test:2.3.9.RELEASE",
"org.springframework.boot:spring-boot-starter-test:2.3.9.RELEASE",
"org.springframework.boot:spring-boot-test-autoconfigure:2.3.9.RELEASE",
"org.mockito:mockito-all:1.10.19",
],
......
Don’t forget to add unpinned dependencies as below.
bazel run @unpinned_maven//:pin
Then, add the testing steps in BUILD.bazel
......java_library(
name = "test-lib",
srcs = glob(["generated/src/test/java/**/*.java"]),
resources = [
],
deps = [
artifact("org.springframework:spring-beans"),
artifact("org.springframework:spring-test"),
artifact("junit:junit"),
artifact("org.springframework.boot:spring-boot-test"),
artifact("org.springframework.boot:spring-boot-test-autoconfigure"),
artifact("org.springframework.boot:spring-boot-starter-test"),
artifact("org.mockito:mockito-all"),
":hello"
]
)java_test(
name = "run-test",
size = "small",
test_class = "com.awesome.tom.api.TestAll",
runtime_deps = [
":test-lib",
]
)
Spring Boot test annotations
- RunWith
This guy starts the Spring application and setups the application context
@RunWith(SpringRunner.class)
- WebMvcTest
This guy setups the test env to use the application context and gets ready to test HelloApiController.class
@WebMvcTest(HelloApiController.class)
- TestPropertySource
This guy replaces the value of my.defaul.hello with new value.
@TestPropertySource(properties = {“my.defaul.hello=hey yah yah”})
Putting all together, this test shows that the values injected by using Value annotation can be replaced by TestPropertySource annotation in the test class:
package com.awesome.tom.api;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.mockito.Mockito.when;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.boot.test.mock.mockito.MockBean;@RunWith(SpringRunner.class)
@WebMvcTest(HelloApiController.class)
@TestPropertySource(properties = {"my.defaul.hello=hey yah yah"})
public class HelloApiControllerTestForValue {
@Autowired
private MockMvc mockMvc; @Test
public void showYouHowTestPropertySourceWorks() throws Exception {
this.mockMvc.perform(get("/hello-service/v1/hello"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().json("{\"language\":\"English\",\"Content\":\"hey yah yah\"}"));
}
}
- MockBean
Sometimes, you want to mock the service in the controller. The MockBean annotation can be used to mock your service:
@MockBean
private HelloService service;
This test shows that the service in the controller can be replaced by a mock service:
package com.awesome.tom.api;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.mockito.Mockito.when;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.boot.test.mock.mockito.MockBean;@RunWith(SpringRunner.class)
@WebMvcTest(HelloApiController.class)
@TestPropertySource(properties = {
"my.defaul.hello=hey yah yah",
})
public class HelloApiControllerTestForService {
@Autowired
private MockMvc mockMvc; @MockBean
private HelloService service;@Test
public void showYouHowMockBeanWorks() throws Exception {
when(service.getHello()).thenReturn("Hello, Mock");
this.mockMvc.perform(get("/hello-service/v1/hello"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().json("{\"language\":\"English\",\"Content\":\"Hello, Mock\"}"));
}
}
// FYI, to get the response body for a post request
// MvcResult mvcResult = this.mockMvc.perform(post("url")
// .contentType(MediaType.APPLICATION_JSON)
// .content("{\"some\":\"json\"}")
// .andDo(print())
// .andExpect(status().isAccepted())
// .andReturn();
// String body = mvcResult.getResponse().getContentAsString();
JUnit test suite to test all the unit tests:
package com.awesome.tom.api;import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;@RunWith(Suite.class)
@Suite.SuiteClasses({
HelloApiControllerTestForService.class,
HelloApiControllerTestForValue.class
})
public class TestAll {
}