|
|
@ -1213,9 +1213,9 @@ configuration. |
|
|
|
|
|
|
|
|
|
|
|
In addition to generic testing infrastructure, the TestContext framework provides |
|
|
|
In addition to generic testing infrastructure, the TestContext framework provides |
|
|
|
explicit support for JUnit and TestNG in the form of `abstract` support classes. For |
|
|
|
explicit support for JUnit and TestNG in the form of `abstract` support classes. For |
|
|
|
JUnit, Spring also provides a custom JUnit `Runner` that allows one to write so-called |
|
|
|
JUnit, Spring also provides a custom JUnit `Runner` and custom JUnit `Rules` that allow |
|
|
|
__POJO test classes__. POJO test classes are not required to extend a particular class |
|
|
|
one to write so-called __POJO test classes__. POJO test classes are not required to |
|
|
|
hierarchy. |
|
|
|
extend a particular class hierarchy. |
|
|
|
|
|
|
|
|
|
|
|
The following section provides an overview of the internals of the TestContext |
|
|
|
The following section provides an overview of the internals of the TestContext |
|
|
|
framework. If you are only interested in using the framework and not necessarily |
|
|
|
framework. If you are only interested in using the framework and not necessarily |
|
|
@ -3759,23 +3759,22 @@ The __Spring MVC Test framework__ provides first class support for testing Sprin |
|
|
|
code using a fluent API that can be used with JUnit, TestNG, or any other testing |
|
|
|
code using a fluent API that can be used with JUnit, TestNG, or any other testing |
|
|
|
framework. It's built on the |
|
|
|
framework. It's built on the |
|
|
|
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/mock/web/package-summary.html[Servlet API mock objects] |
|
|
|
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/mock/web/package-summary.html[Servlet API mock objects] |
|
|
|
from the `spring-test` module and hence does not require a running Servlet container, |
|
|
|
from the `spring-test` module and hence does _not_ use a running Servlet container. It |
|
|
|
it uses the `DispatcherServlet` thus providing full Spring MVC support, and |
|
|
|
uses the `DispatcherServlet` to provide full Spring MVC runtime behavior and provides support |
|
|
|
may optionally load actual Spring configuration with the __TestContext framework__ |
|
|
|
for loading actual Spring configuration with the __TestContext framework__ in addition to a |
|
|
|
in addition to a standalone mode in which controllers may be instantiated manually |
|
|
|
standalone mode in which controllers may be instantiated manually and tested one at a time. |
|
|
|
and tested one at a time. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__Spring MVC Test__ also provides client-side support for testing code that uses |
|
|
|
__Spring MVC Test__ also provides client-side support for testing code that uses |
|
|
|
the `RestTemplate`. Client-side tests mock the server responses and also do not |
|
|
|
the `RestTemplate`. Client-side tests mock the server responses and also do _not_ |
|
|
|
require a running server. |
|
|
|
use a running server. |
|
|
|
|
|
|
|
|
|
|
|
[TIP] |
|
|
|
[TIP] |
|
|
|
==== |
|
|
|
==== |
|
|
|
Spring Boot provides an option to write full, end-to-end integration tests that include |
|
|
|
Spring Boot provides an option to write full, end-to-end integration tests that include |
|
|
|
a running server. If this is your goal please have a look at the |
|
|
|
a running server. If this is your goal please have a look at the |
|
|
|
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications[Spring Boot reference page]. |
|
|
|
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications[Spring Boot reference page]. |
|
|
|
For more on the difference with end-to-end integration tests see |
|
|
|
For more information on the differences between out-of-container and end-to-end |
|
|
|
<<spring-mvc-test-vs-end-to-end-integration-tests>>. |
|
|
|
integration tests, see <<spring-mvc-test-vs-end-to-end-integration-tests>>. |
|
|
|
==== |
|
|
|
==== |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -3790,8 +3789,8 @@ mappings, data binding, type conversion, validation, and much more. Furthermore, |
|
|
|
controller methods such as `@InitBinder`, `@ModelAttribute`, and `@ExceptionHandler` may |
|
|
|
controller methods such as `@InitBinder`, `@ModelAttribute`, and `@ExceptionHandler` may |
|
|
|
also be invoked as part of the request processing lifecycle. |
|
|
|
also be invoked as part of the request processing lifecycle. |
|
|
|
|
|
|
|
|
|
|
|
The goal of __Spring MVC Test__ is to provide an effective way of testing controllers |
|
|
|
The goal of __Spring MVC Test__ is to provide an effective way for testing controllers |
|
|
|
by performing requests and generating responses through the `DispatcherServlet`. |
|
|
|
by performing requests and generating responses through the actual `DispatcherServlet`. |
|
|
|
|
|
|
|
|
|
|
|
__Spring MVC Test__ builds on the familiar <<mock-objects-servlet,"mock" implementations |
|
|
|
__Spring MVC Test__ builds on the familiar <<mock-objects-servlet,"mock" implementations |
|
|
|
of the Servlet API>> available in the `spring-test` module. This allows performing |
|
|
|
of the Servlet API>> available in the `spring-test` module. This allows performing |
|
|
@ -3832,14 +3831,14 @@ JUnit-based example of using Spring MVC Test: |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
The above test relies on the `WebApplicationContext` support of the __TestContext framework__ |
|
|
|
The above test relies on the `WebApplicationContext` support of the __TestContext framework__ |
|
|
|
to loads Spring configuration from an XML configuration file located in the same package |
|
|
|
for loading Spring configuration from an XML configuration file located in the same package |
|
|
|
as the test class but also supported is Java-based configuration. See these |
|
|
|
as the test class, but Java-based and Groovy-based configuration are also supported. See these |
|
|
|
https://github.com/spring-projects/spring-framework/tree/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context[sample tests]. |
|
|
|
https://github.com/spring-projects/spring-framework/tree/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context[sample tests]. |
|
|
|
|
|
|
|
|
|
|
|
The `MockMvc` instance is used to perform a request to `"/accounts/1"` and verify the |
|
|
|
The `MockMvc` instance is used to perform a `GET` request to `"/accounts/1"` and verify |
|
|
|
resulting response has status 200, content type is `"application/json"`, and |
|
|
|
that the resulting response has status 200, the content type is `"application/json"`, and the |
|
|
|
response body has a JSON property called "name" with the value "Lee". The jsonPath |
|
|
|
response body has a JSON property called "name" with the value "Lee". The `jsonPath` |
|
|
|
syntax is supported through the Jayway https://github.com/jayway/JsonPath[JsonPath |
|
|
|
syntax is supported through the Jayway https://github.com/jayway/JsonPath[JsonPath |
|
|
|
project]. There are lots of other options for verifying the result of the performed |
|
|
|
project]. There are lots of other options for verifying the result of the performed |
|
|
|
request that will be discussed below. |
|
|
|
request that will be discussed below. |
|
|
|
|
|
|
|
|
|
|
@ -3860,7 +3859,7 @@ completion on static members. |
|
|
|
There are two main options for creating an instance of `MockMvc`. |
|
|
|
There are two main options for creating an instance of `MockMvc`. |
|
|
|
The first is to load Spring MVC configuration through the __TestContext |
|
|
|
The first is to load Spring MVC configuration through the __TestContext |
|
|
|
framework__, which loads the Spring configuration and injects a `WebApplicationContext` |
|
|
|
framework__, which loads the Spring configuration and injects a `WebApplicationContext` |
|
|
|
into the test to use to create a `MockMvc`: |
|
|
|
into the test to use to build a `MockMvc` instance: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -4000,7 +3999,7 @@ Or you can add Servlet request parameters representing either query of form para |
|
|
|
If application code relies on Servlet request parameters and doesn't check the query |
|
|
|
If application code relies on Servlet request parameters and doesn't check the query |
|
|
|
string explicitly (as is most often the case) then it doesn't matter which option you use. |
|
|
|
string explicitly (as is most often the case) then it doesn't matter which option you use. |
|
|
|
Keep in mind however that query params provided with the URI template will be decoded while |
|
|
|
Keep in mind however that query params provided with the URI template will be decoded while |
|
|
|
request parameters provided through the `param(...)` method are expected to be decoded. |
|
|
|
request parameters provided through the `param(...)` method are expected to already be decoded. |
|
|
|
|
|
|
|
|
|
|
|
In most cases it's preferable to leave out the context path and the Servlet path from |
|
|
|
In most cases it's preferable to leave out the context path and the Servlet path from |
|
|
|
the request URI. If you must test with the full request URI, be sure to set the |
|
|
|
the request URI. If you must test with the full request URI, be sure to set the |
|
|
@ -4048,19 +4047,20 @@ performing a request: |
|
|
|
mockMvc.perform(get("/accounts/1")).andExpect(status().isOk()); |
|
|
|
mockMvc.perform(get("/accounts/1")).andExpect(status().isOk()); |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
`MockMvcResultMatchers.*` provides a number of expectations some of which are further |
|
|
|
`MockMvcResultMatchers.*` provides a number of expectations, some of which are further |
|
|
|
nested with more detailed expectations. |
|
|
|
nested with more detailed expectations. |
|
|
|
|
|
|
|
|
|
|
|
Expectations fall in two general categories. The first category of assertions verify |
|
|
|
Expectations fall in two general categories. The first category of assertions verifies |
|
|
|
properties of the response, i.e the response status, headers, and content. Those |
|
|
|
properties of the response: for example, the response status, headers, and content. These |
|
|
|
are the most important results to assert. |
|
|
|
are the most important results to assert. |
|
|
|
|
|
|
|
|
|
|
|
The second category of assertions go beyond the response. They allow inspecting Spring |
|
|
|
The second category of assertions goes beyond the response. These assertions allow |
|
|
|
MVC specific things such as which controller method processed the request, whether |
|
|
|
one to inspect Spring MVC specific aspects such as which controller method processed |
|
|
|
an exception was raised and handled, what the content of the model is, what view was |
|
|
|
the request, whether an exception was raised and handled, what the content of the model |
|
|
|
selected, what flash attributes were added, and so on. They also allow inspecting |
|
|
|
is, what view was selected, what flash attributes were added, and so on. They also allow |
|
|
|
Servlet specific things such as request and session attributes. The following test |
|
|
|
one to inspect Servlet specific aspects such as request and session attributes. |
|
|
|
asserts that binding/validation failed: |
|
|
|
|
|
|
|
|
|
|
|
The following test asserts that binding or validation failed: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -4085,7 +4085,7 @@ This can be done as follows, where `print()` is a static import from |
|
|
|
|
|
|
|
|
|
|
|
As long as request processing does not cause an unhandled exception, the `print()` method |
|
|
|
As long as request processing does not cause an unhandled exception, the `print()` method |
|
|
|
will print all the available result data to `System.out`. Spring Framework 4.2 introduces |
|
|
|
will print all the available result data to `System.out`. Spring Framework 4.2 introduces |
|
|
|
a new `log()` method and two additional variants of the `print()` method: one that accepts |
|
|
|
a `log()` method and two additional variants of the `print()` method, one that accepts |
|
|
|
an `OutputStream` and one that accepts a `Writer`. For example, invoking |
|
|
|
an `OutputStream` and one that accepts a `Writer`. For example, invoking |
|
|
|
`print(System.err)` will print the result data to `System.err`; while invoking |
|
|
|
`print(System.err)` will print the result data to `System.err`; while invoking |
|
|
|
`print(myWriter)` will print the result data to a custom writer. If you would like to |
|
|
|
`print(myWriter)` will print the result data to a custom writer. If you would like to |
|
|
@ -4094,8 +4094,8 @@ will log the result data as a single `DEBUG` message under the |
|
|
|
`org.springframework.test.web.servlet.result` logging category. |
|
|
|
`org.springframework.test.web.servlet.result` logging category. |
|
|
|
|
|
|
|
|
|
|
|
In some cases, you may want to get direct access to the result and verify something that |
|
|
|
In some cases, you may want to get direct access to the result and verify something that |
|
|
|
cannot be verified otherwise. This can be done by appending `.andReturn()` at the end |
|
|
|
cannot be verified otherwise. This can be achieved by appending `.andReturn()` after all |
|
|
|
after all expectations: |
|
|
|
other expectations: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -4104,7 +4104,7 @@ after all expectations: |
|
|
|
// ... |
|
|
|
// ... |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
When all tests repeat the same expectations you can set up common expectations once |
|
|
|
If all tests repeat the same expectations you can set up common expectations once |
|
|
|
when building the `MockMvc` instance: |
|
|
|
when building the `MockMvc` instance: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
@ -4116,12 +4116,12 @@ when building the `MockMvc` instance: |
|
|
|
.build() |
|
|
|
.build() |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
Note that the expectation is __always__ applied and cannot be overridden without |
|
|
|
Note that common expectations are __always__ applied and cannot be overridden without |
|
|
|
creating a separate `MockMvc` instance. |
|
|
|
creating a separate `MockMvc` instance. |
|
|
|
|
|
|
|
|
|
|
|
When JSON response content contains hypermedia links created with |
|
|
|
When JSON response content contains hypermedia links created with |
|
|
|
https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], the resulting links can |
|
|
|
https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], the resulting links can |
|
|
|
be verified: |
|
|
|
be verified using JsonPath expressions: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -4132,7 +4132,7 @@ be verified: |
|
|
|
|
|
|
|
|
|
|
|
When XML response content contains hypermedia links created with |
|
|
|
When XML response content contains hypermedia links created with |
|
|
|
https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], the resulting links can |
|
|
|
https://github.com/spring-projects/spring-hateoas[Spring HATEOAS], the resulting links can |
|
|
|
be verified: |
|
|
|
be verified using XPath expressions: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -4144,7 +4144,7 @@ be verified: |
|
|
|
|
|
|
|
|
|
|
|
[[spring-mvc-test-server-filters]] |
|
|
|
[[spring-mvc-test-server-filters]] |
|
|
|
===== Filter Registrations |
|
|
|
===== Filter Registrations |
|
|
|
When setting up a `MockMvc`, you can register one or more `Filter` instances: |
|
|
|
When setting up a `MockMvc` instance, you can register one or more Servlet `Filter` instances: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0] |
|
|
|
[source,java,indent=0] |
|
|
|
[subs="verbatim,quotes"] |
|
|
|
[subs="verbatim,quotes"] |
|
|
@ -4152,53 +4152,55 @@ When setting up a `MockMvc`, you can register one or more `Filter` instances: |
|
|
|
mockMvc = standaloneSetup(new PersonController()).addFilters(new CharacterEncodingFilter()).build(); |
|
|
|
mockMvc = standaloneSetup(new PersonController()).addFilters(new CharacterEncodingFilter()).build(); |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
Registered filters will be invoked through `MockFilterChain` from `spring-test` and the |
|
|
|
Registered filters will be invoked through via the `MockFilterChain` from `spring-test`, and the |
|
|
|
last filter will delegates to the `DispatcherServlet`. |
|
|
|
last filter will delegate to the `DispatcherServlet`. |
|
|
|
|
|
|
|
|
|
|
|
[[spring-mvc-test-vs-end-to-end-integration-tests]] |
|
|
|
[[spring-mvc-test-vs-end-to-end-integration-tests]] |
|
|
|
===== Difference With End-to-End Integration Tests |
|
|
|
===== Differences between Out-of-Container and End-to-End Integration Tests |
|
|
|
|
|
|
|
|
|
|
|
As mentioned earlier __Spring MVC Test__ is built on the Servlet API mock objects from |
|
|
|
As mentioned earlier __Spring MVC Test__ is built on the Servlet API mock objects from |
|
|
|
the `spring-test` module and does not rely on a running Servlet container. Therefore |
|
|
|
the `spring-test` module and does not use a running Servlet container. Therefore |
|
|
|
there are some important differences compared to full end-to-end integration tests |
|
|
|
there are some important differences compared to full end-to-end integration tests |
|
|
|
with an actual client and server running. |
|
|
|
with an actual client and server running. |
|
|
|
|
|
|
|
|
|
|
|
The easiest way to think about this is starting with a blank `MockHttpServletRequest`. |
|
|
|
The easiest way to think about this is starting with a blank `MockHttpServletRequest`. |
|
|
|
Whatever you add to it is what the request will be. The things that may catch you out are |
|
|
|
Whatever you add to it is what the request will be. Things that may catch you by surprise |
|
|
|
there is no context path by default, no jsessionid cookie, no forwarding, error, or async |
|
|
|
are that there is no context path by default, no `jsessionid` cookie, no forwarding, error, |
|
|
|
dispatches, and therefore no actual JSP rendering. Instead "forwarded" and "redirected" |
|
|
|
or async dispatches, and therefore no actual JSP rendering. Instead, "forwarded" and |
|
|
|
URLs are saved in the `MockHttpServletResponse` and can be asserted with expectations. |
|
|
|
"redirected" URLs are saved in the `MockHttpServletResponse` and can be asserted with |
|
|
|
|
|
|
|
expectations. |
|
|
|
|
|
|
|
|
|
|
|
This means if you are using JSPs you can verify the JSP page to which the request was |
|
|
|
This means if you are using JSPs you can verify the JSP page to which the request was |
|
|
|
forwarded but there won't be any HTML rendered. Note however that all other rendering |
|
|
|
forwarded, but there won't be any HTML rendered. In other words, the JSP will not be |
|
|
|
technologies that don't rely on forwarding such as Thymeleaf, Freemarker, Velocity |
|
|
|
_invoked_. Note however that all other rendering technologies which don't rely on |
|
|
|
will render HTML to the response body as expected. The same is true for rendering JSON, |
|
|
|
forwarding such as Thymeleaf, Freemarker, and Velocity will render HTML to the response |
|
|
|
XML and others via `@ResponseBody` methods. |
|
|
|
body as expected. The same is true for rendering JSON, XML, and other formats via |
|
|
|
|
|
|
|
`@ResponseBody` methods. |
|
|
|
|
|
|
|
|
|
|
|
Alternatively you may consider the full end-to-end integration testing support from |
|
|
|
Alternatively you may consider the full end-to-end integration testing support from |
|
|
|
Spring Boot via `@WebIntegrationTest`. See the |
|
|
|
Spring Boot via `@WebIntegrationTest`. See the |
|
|
|
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications[Spring Boot reference]. |
|
|
|
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications[Spring Boot reference]. |
|
|
|
|
|
|
|
|
|
|
|
There are pros and cons for each. The options provided in __Spring MVC Test__ |
|
|
|
There are pros and cons for each approach. The options provided in __Spring MVC Test__ |
|
|
|
are different stops on the scale from classic unit to full integration tests. |
|
|
|
are different stops on the scale from classic unit testing to full integration testing. |
|
|
|
To be sure none of the options in Spring MVC Test are classic unit tests but they are a |
|
|
|
To be certain, none of the options in Spring MVC Test fall under the category of classic |
|
|
|
little closer to it. For example you can isolate the service layer with mocks |
|
|
|
unit testing, but they _are_ a little closer to it. For example, you can isolate the web |
|
|
|
injected into controllers and then you're testing the web layer only through |
|
|
|
layer by injecting mocked services into controllers, in which case you're testing the web |
|
|
|
the `DispatcherServlet` and with actual Spring configuration, just like you might test |
|
|
|
layer only through the `DispatcherServlet` but with actual Spring configuration, just |
|
|
|
the database layer in isolation of the layers above. Or you could be using the |
|
|
|
like you might test the data access layer in isolation from the layers above. Or you |
|
|
|
standalone setup focusing on one controller at a time and manually providing the |
|
|
|
can use the standalone setup focusing on one controller at a time and manually providing |
|
|
|
configuration required to make it work. |
|
|
|
the configuration required to make it work. |
|
|
|
|
|
|
|
|
|
|
|
Another important distinction when using __Spring MVC Test__ is that conceptually such |
|
|
|
Another important distinction when using __Spring MVC Test__ is that conceptually such |
|
|
|
tests are on the inside of the server-side so you can check what handler was used, |
|
|
|
tests are on the _inside_ of the server-side so you can check what handler was used, |
|
|
|
if an exception was handled with a HandlerExceptionResolver, what the content of the |
|
|
|
if an exception was handled with a HandlerExceptionResolver, what the content of the |
|
|
|
model is, what binding errors there were, etc. That means it's easier to write |
|
|
|
model is, what binding errors there were, etc. That means it's easier to write |
|
|
|
expectations since the server is not a black box as it is when testing it through |
|
|
|
expectations since the server is not a black box as it is when testing it through |
|
|
|
an actual HTTP client. This is generally the advantage of classic unit testing that it's |
|
|
|
an actual HTTP client. This is generally an advantage of classic unit testing, that it's |
|
|
|
easier to write, reason about, and debug but does not replace the need for full |
|
|
|
easier to write, reason about, and debug but does not replace the need for full |
|
|
|
integration tests. At the same time it's important not to lose sight of the fact |
|
|
|
integration tests. At the same time it's important not to lose sight of the fact that |
|
|
|
the response is the most important thing to check. In short there is room here for |
|
|
|
the response is the most important thing to check. In short, there is room here for |
|
|
|
multiple styles and strategies of testing even in the same project. |
|
|
|
multiple styles and strategies of testing even within the same project. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[spring-mvc-test-server-resources]] |
|
|
|
[[spring-mvc-test-server-resources]] |
|
|
|