Testing: controller
This commit is contained in:
parent
8e7f231d1f
commit
45d0361548
35
README.md
35
README.md
@ -169,9 +169,15 @@ Spring interprets the `@Autowired` annotation, and the controller is injected be
|
||||
|
||||
> A nice feature of the Spring Test support is that the application context is cached between tests. That way, if you have multiple methods in a test case or multiple test cases with the same configuration, they incur the cost of starting the application only once. You can control the cache by using the @DirtiesContext annotation.
|
||||
|
||||
## Test HTTP requests
|
||||
It is nice to have a sanity check, but you should also write some tests that assert the behavior of your application.
|
||||
|
||||
It is nice to have a sanity check, but you should also write some tests that assert the behavior of your application. To do that, you could start the application and listen for a connection (as it would do in production) and then send an HTTP request and assert the response. The following listing (from `src/test/java/djmil/hellomvc/HttpRequestTest.java`) shows how to do so:
|
||||
## Testing depth
|
||||
|
||||
You can as SpringBoot to test your app at the different depth. Trading test coverage for speed.
|
||||
|
||||
### HTTP requests: application
|
||||
|
||||
Here, we are starting our application and listen for a connection (as it would do in production) and then send an HTTP request and assert the response. The following listing (from `src/test/java/djmil/hellomvc/HttpRequestTest.java`) shows how to do so:
|
||||
|
||||
```java
|
||||
package djmil.hellomvc;
|
||||
@ -205,7 +211,7 @@ public class HttpRequestTest {
|
||||
|
||||
Note the use of `webEnvironment=RANDOM_PORT` to start the server with a random port (useful to avoid conflicts in test environments) and the injection of the port with `@LocalServerPort`. Also, note that Spring Boot has automatically provided a `TestRestTemplate` for you. All you have to do is add `@Autowired` to it.
|
||||
|
||||
## Test Web app only
|
||||
### Web app only
|
||||
|
||||
Another useful approach is **to not start the server at all** but to test only the layer below that, where Spring handles the incoming HTTP request and hands it off to your controller. That way, almost of the full stack is used, and your code will be called in exactly the same way as if it were processing a real HTTP request but without the cost of starting the server. To do that, use Spring’s `MockMvc` and ask for that to be injected for you by using the `@AutoConfigureMockMvc` annotation on the test case. The following listing (from `src/test/java/djmil/hellomvc/WebApplicationTest.java`) shows how to do so:
|
||||
|
||||
@ -242,4 +248,25 @@ public class WebApplicationTest {
|
||||
}
|
||||
```
|
||||
|
||||
In this test, the full Spring application context is started but without the server.
|
||||
In this test, the full Spring application context is started but without the server.
|
||||
|
||||
### Controller: web layer only
|
||||
|
||||
We can narrow the tests to only the web layer by using `@WebMvcTest`, as the following listing (from `src/test/java/djmil/hellomvc/WebLayerTest.java`) shows:
|
||||
|
||||
```java
|
||||
@WebMvcTest
|
||||
public class WebLayerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
public void shouldReturnDefaultMessage() throws Exception {
|
||||
this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString("Hello, World")));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The test assertion is the same as in the previous case. However, in this test, Spring Boot instantiates only the web layer rather than the whole context. In an application with multiple controllers, you can even ask for only one to be instantiated by using, for example, `@WebMvcTest(HomeController.class)`.
|
27
src/test/java/djmil/hellomvc/WebLayerTest.java
Normal file
27
src/test/java/djmil/hellomvc/WebLayerTest.java
Normal file
@ -0,0 +1,27 @@
|
||||
package djmil.hellomvc;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
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 org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
@WebMvcTest
|
||||
public class WebLayerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
public void shouldReturnDefaultMessage() throws Exception {
|
||||
this.mockMvc.perform(get("/greeting"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString("Hello, World")));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user