Document AssertJ support for MockMvc
This commit restructures the section on MockMvc so that the anchors are easier to read. The standard integration has moved to a Hamcrest Integration section at the same level as HtmlUnit Integration, and a new AssertJ Integration section has been created. Closes gh-32454
This commit is contained in:
parent
7d236e29bb
commit
d43dba63a1
|
@ -49,6 +49,7 @@ dependencies {
|
|||
api(project(":spring-webmvc"))
|
||||
api(project(":spring-context-support"))
|
||||
api(project(":spring-aspects"))
|
||||
api(project(":spring-test"))
|
||||
api(project(":spring-websocket"))
|
||||
|
||||
api("org.jetbrains.kotlin:kotlin-stdlib")
|
||||
|
|
|
@ -142,23 +142,30 @@
|
|||
*** xref:testing/testcontext-framework/support-classes.adoc[]
|
||||
*** xref:testing/testcontext-framework/aot.adoc[]
|
||||
** xref:testing/webtestclient.adoc[]
|
||||
** xref:testing/spring-mvc-test-framework.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-static-imports.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-setup-options.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-setup-steps.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-performing-requests.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-defining-expectations.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/async-requests.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/vs-streaming-response.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-filters.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/vs-end-to-end-integration-tests.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-resources.adoc[]
|
||||
*** xref:testing/spring-mvc-test-framework/server-htmlunit.adoc[]
|
||||
**** xref:testing/spring-mvc-test-framework/server-htmlunit/why.adoc[]
|
||||
**** xref:testing/spring-mvc-test-framework/server-htmlunit/mah.adoc[]
|
||||
**** xref:testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc[]
|
||||
**** xref:testing/spring-mvc-test-framework/server-htmlunit/geb.adoc[]
|
||||
** xref:testing/mockmvc.adoc[]
|
||||
*** xref:testing/mockmvc/overview.adoc[]
|
||||
*** xref:testing/mockmvc/setup-options.adoc[]
|
||||
*** xref:testing/mockmvc/hamcrest.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/static-imports.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/setup.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/setup-steps.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/requests.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/expectations.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/async-requests.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/vs-streaming-response.adoc[]
|
||||
**** xref:testing/mockmvc/hamcrest/filters.adoc[]
|
||||
*** xref:testing/mockmvc/assertj.adoc[]
|
||||
**** xref:testing/mockmvc/assertj/setup.adoc[]
|
||||
**** xref:testing/mockmvc/assertj/requests.adoc[]
|
||||
**** xref:testing/mockmvc/assertj/assertions.adoc[]
|
||||
**** xref:testing/mockmvc/assertj/integration.adoc[]
|
||||
*** xref:testing/mockmvc/htmlunit.adoc[]
|
||||
**** xref:testing/mockmvc/htmlunit/why.adoc[]
|
||||
**** xref:testing/mockmvc/htmlunit/mah.adoc[]
|
||||
**** xref:testing/mockmvc/htmlunit/webdriver.adoc[]
|
||||
**** xref:testing/mockmvc/htmlunit/geb.adoc[]
|
||||
*** xref:testing/mockmvc/vs-end-to-end-integration-tests.adoc[]
|
||||
*** xref:testing/mockmvc/resources.adoc[]
|
||||
** xref:testing/spring-mvc-test-client.adoc[]
|
||||
** xref:testing/appendix.adoc[]
|
||||
*** xref:testing/annotations.adoc[]
|
||||
|
|
|
@ -30,7 +30,7 @@ integration support, and the rest of this chapter then focuses on dedicated topi
|
|||
* xref:testing/support-jdbc.adoc[JDBC Testing Support]
|
||||
* xref:testing/testcontext-framework.adoc[Spring TestContext Framework]
|
||||
* xref:testing/webtestclient.adoc[WebTestClient]
|
||||
* xref:testing/spring-mvc-test-framework.adoc[MockMvc]
|
||||
* xref:testing/mockmvc.adoc[MockMvc]
|
||||
* xref:testing/spring-mvc-test-client.adoc[Testing Client Applications]
|
||||
* xref:testing/annotations.adoc[Annotations]
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
[[mockmvc]]
|
||||
= MockMvc
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
MockMvc provides support for testing Spring MVC applications. It performs full Spring MVC
|
||||
request handling but via mock request and response objects instead of a running server.
|
||||
|
||||
MockMvc can be used on its own to perform requests and verify responses responses using
|
||||
Hamcrest, or through `MockMvcTester` that provides a fluent API using AssertJ. Finally,
|
||||
it can also be used through the xref:testing/webtestclient.adoc[WebTestClient] where
|
||||
MockMvc is plugged in as the server to handle requests with. The advantage of
|
||||
`WebTestClient` is the option to work with higher level objects instead of raw data as
|
||||
well as the ability to switch to full, end-to-end HTTP tests against a live server and
|
||||
use the same test API.
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[[mockmvc-tester]]
|
||||
= AssertJ Integration
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The AssertJ integration builds on top of plain `MockMvc` with several differences:
|
||||
|
||||
* There is no need to use static imports as both the requests and assertions can be
|
||||
crafted using a fluent API.
|
||||
* Unresolved exceptions are handled consistently so that your tests do not need to
|
||||
throw (or catch) `Exception`.
|
||||
* By default, the result to assert is complete whether the processing is asynchronous
|
||||
or not. In other words, there is no need for special handling for Async requests.
|
||||
|
||||
`MockMvcTester` is the entry point for the AssertJ support. It allows to craft the
|
||||
request and return a result that is AssertJ compatible so that it can be wrapped in
|
||||
a standard `assertThat()` method.
|
|
@ -0,0 +1,49 @@
|
|||
[[mockmvc-tester-assertions]]
|
||||
= Defining Expectations
|
||||
|
||||
Assertions work the same way as any AssertJ assertions. The support provides dedicated
|
||||
assert objects for the various pieces of the `MvcTestResult`, as shown in the following
|
||||
example:
|
||||
|
||||
include-code::./HotelControllerTests[tag=get,indent=0]
|
||||
|
||||
If a request fails, the exchange does not throw the exception. Rather, you can assert
|
||||
that the result of the exchange has failed:
|
||||
|
||||
include-code::./HotelControllerTests[tag=failure,indent=0]
|
||||
|
||||
The request could also fail unexpectedly, that is the exception thrown by the handler
|
||||
has not been handled and is thrown as is. You can still use `.hasFailed()` and
|
||||
`.failure()` but any attempt to access part of the result will throw an exception as
|
||||
the exchange hasn't completed.
|
||||
|
||||
[[mockmvc-tester-assertions-json]]
|
||||
== JSON Support
|
||||
|
||||
The AssertJ support for `MvcTestResult` provides JSON support via `bodyJson()`.
|
||||
|
||||
If https://github.com/jayway/JsonPath[JSONPath] is available, you can apply an expression
|
||||
on the JSON document. The returned value provides convenient methods to return a dedicated
|
||||
assert object for the various supported JSON data types:
|
||||
|
||||
include-code::./FamilyControllerTests[tag=extract-asmap,indent=0]
|
||||
|
||||
You can also convert the raw content to any of your data types as long as the message
|
||||
converter is configured properly:
|
||||
|
||||
include-code::./FamilyControllerTests[tag=extract-convert,indent=0]
|
||||
|
||||
Converting to a target `Class` provides a generic assert object. For more complex types,
|
||||
you may want to use `AssertFactory` instead that returns a dedicated assert type, if
|
||||
possible:
|
||||
|
||||
include-code::./FamilyControllerTests[tag=extract-convert-assert-factory,indent=0]
|
||||
|
||||
https://jsonassert.skyscreamer.org[JSONAssert] is also supported. The body of the
|
||||
response can be matched against a `Resource` or a content. If the content ends with
|
||||
`.json ` we look for a file matching that name on the classpath:
|
||||
|
||||
include-code::./FamilyControllerTests[tag=assert-file,indent=0]
|
||||
|
||||
If you prefer to use another library, you can provide an implementation of
|
||||
{spring-framework-api}/test/json/JsonComparator.html[`JsonComparator`].
|
|
@ -0,0 +1,23 @@
|
|||
[[mockmvc-tester-integration]]
|
||||
= MockMvc integration
|
||||
|
||||
If you want to use the AssertJ support but have invested in the original `MockMvc`
|
||||
API, `MockMvcTester` offers several ways to integrate with it.
|
||||
|
||||
If you have your own `RequestBuilder` implementation, you can trigger the processing
|
||||
of the request using `perform`. The example below showcases how the query can be
|
||||
crafted with the original API:
|
||||
|
||||
include-code::./HotelControllerTests[tag=perform,indent=0]
|
||||
|
||||
Similarly, if you have crafted custom matchers that you use with the `.andExpect` feature
|
||||
of `MockMvc` you can use them via `.matches`. In the example below, we rewrite the
|
||||
preceding example to assert the status with the `ResultMatcher` implementation that
|
||||
`MockMvc` provides:
|
||||
|
||||
include-code::./HotelControllerTests[tag=matches,indent=0]
|
||||
|
||||
`MockMvc` also defines a `ResultHandler` contract that lets you execute arbitrary actions
|
||||
on `MvcResult`. If you have implemented this contract you can invoke it using `.apply`.
|
||||
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
[[mockmvc-tester-requests]]
|
||||
= Performing Requests
|
||||
|
||||
This section shows how to use `MockMvcTester` to perform requests and its integration
|
||||
with AssertJ to verify responses.
|
||||
|
||||
`MockMvcTester` provides a fluent API to compose the request that reuses the same
|
||||
`MockHttpServletRequestBuilder` as the Hamcrest support, except that there is no need
|
||||
to import a static method. The builder that is returned is AssertJ-aware so that
|
||||
wrapping it in the regular `assertThat()` factory method triggers the exchange and
|
||||
provides access to a dedicated Assert object for `MvcTestResult`.
|
||||
|
||||
Here is a simple example that performs a `POST` on `/hotels/42` and configures the
|
||||
request to specify an `Accept` header:
|
||||
|
||||
include-code::./HotelControllerTests[tag=post,indent=0]
|
||||
|
||||
AssertJ often consists of multiple `assertThat()` statements to validate the different
|
||||
parts of the exchange. Rather than having a single statement as in the case above, you
|
||||
can use `.exchange()` to return a `MvcTestResult` that can be used in multiple
|
||||
`assertThat` statements:
|
||||
|
||||
include-code::./HotelControllerTests[tag=post-exchange,indent=0]
|
||||
|
||||
You can specify query parameters in URI template style, as the following example shows:
|
||||
|
||||
include-code::./HotelControllerTests[tag=query-parameters,indent=0]
|
||||
|
||||
You can also add Servlet request parameters that represent either query or form
|
||||
parameters, as the following example shows:
|
||||
|
||||
include-code::./HotelControllerTests[tag=parameters,indent=0]
|
||||
|
||||
If application code relies on Servlet request parameters and does not check the query
|
||||
string explicitly (as is most often the case), it does not matter which option you use.
|
||||
Keep in mind, however, that query parameters provided with the URI template are decoded
|
||||
while request parameters provided through the `param(...)` method are expected to already
|
||||
be decoded.
|
||||
|
||||
|
||||
[[mockmvc-tester-requests-async]]
|
||||
== Async
|
||||
|
||||
If the processing of the request is done asynchronously, `exchange()` waits for
|
||||
the completion of the request so that the result to assert is effectively immutable.
|
||||
The default timeout is 10 seconds but it can be controlled on a request-by-request
|
||||
basis as shown in the following example:
|
||||
|
||||
include-code::./AsyncControllerTests[tag=duration,indent=0]
|
||||
|
||||
If you prefer to get the raw result and manage the lifecycle of the asynchronous
|
||||
request yourself, use `asyncExchange` rather than `exchange`.
|
||||
|
||||
[[mockmvc-tester-requests-multipart]]
|
||||
== Multipart
|
||||
|
||||
You can perform file upload requests that internally use
|
||||
`MockMultipartHttpServletRequest` so that there is no actual parsing of a multipart
|
||||
request. Rather, you have to set it up to be similar to the following example:
|
||||
|
||||
include-code::./MultipartControllerTests[tag=snippet,indent=0]
|
||||
|
||||
[[mockmvc-tester-requests-paths]]
|
||||
== Using Servlet and Context Paths
|
||||
|
||||
In most cases, it is preferable to leave the context path and the Servlet path out of the
|
||||
request URI. If you must test with the full request URI, be sure to set the `contextPath`
|
||||
and `servletPath` accordingly so that request mappings work, as the following example
|
||||
shows:
|
||||
|
||||
include-code::./HotelControllerTests[tag=context-servlet-paths,indent=0]
|
||||
|
||||
In the preceding example, it would be cumbersome to set the `contextPath` and
|
||||
`servletPath` with every performed request. Instead, you can set up default request
|
||||
properties, as the following example shows:
|
||||
|
||||
include-code::./HotelControllerTests[tag=default-customizations,indent=0]
|
||||
|
||||
The preceding properties affect every request performed through the `mockMvc` instance.
|
||||
If the same property is also specified on a given request, it overrides the default
|
||||
value. That is why the HTTP method and URI in the default request do not matter, since
|
||||
they must be specified on every request.
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
[[mockmvc-tester-setup]]
|
||||
= Configuring MockMvcTester
|
||||
|
||||
`MockMvcTester` can be setup in one of two ways. One is to point directly to the
|
||||
controllers you want to test and programmatically configure Spring MVC infrastructure.
|
||||
The second is to point to Spring configuration with Spring MVC and controller
|
||||
infrastructure in it.
|
||||
|
||||
TIP: For a comparison of those two modes, check xref:testing/mockmvc/setup-options.adoc[Setup Options].
|
||||
|
||||
To set up `MockMvcTester` for testing a specific controller, use the following:
|
||||
|
||||
include-code::./AccountControllerStandaloneTests[tag=snippet,indent=0]
|
||||
|
||||
To set up `MockMvcTester` through Spring configuration, use the following:
|
||||
|
||||
include-code::./AccountControllerIntegrationTests[tag=snippet,indent=0]
|
||||
|
||||
`MockMvcTester` can convert the JSON response body, or the result of a JSONPath expression,
|
||||
to one of your domain object as long as the relevant `HttpMessageConverter` is registered.
|
||||
|
||||
If you use Jackson to serialize content to JSON, the following example registers the
|
||||
converter:
|
||||
|
||||
include-code::./converter/AccountControllerIntegrationTests[tag=snippet,indent=0]
|
||||
|
||||
NOTE: The above assumes the converter has been registered as a Bean.
|
||||
|
||||
Finally, if you have a `MockMvc` instance handy, you can create a `MockMvcTester` by
|
||||
providing the `MockMvc` instance to use using the `create` factory method.
|
|
@ -0,0 +1,7 @@
|
|||
[[mockmvc-server]]
|
||||
= Hamcrest Integration
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
Plain `MockMvc` provides an API to build the request using a builder-style approach
|
||||
that can be initiated with static imports. Hamcrest is used to define expectations and
|
||||
it provides many out-of-the-box options for common needs.
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-async-requests]]
|
||||
[[mockmvc-async-requests]]
|
||||
= Async Requests
|
||||
|
||||
This section shows how to use MockMvc on its own to test asynchronous request handling.
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server-defining-expectations]]
|
||||
[[mockmvc-server-defining-expectations]]
|
||||
= Defining Expectations
|
||||
|
||||
You can define expectations by appending one or more `andExpect(..)` calls after
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server-filters]]
|
||||
[[mockmvc-server-filters]]
|
||||
= Filter Registrations
|
||||
:page-section-summary-toc: 1
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server-performing-requests]]
|
||||
[[mockmvc-server-performing-requests]]
|
||||
= Performing Requests
|
||||
|
||||
This section shows how to use MockMvc on its own to perform requests and verify responses.
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server-setup-steps]]
|
||||
[[mockmvc-server-setup-steps]]
|
||||
= Setup Features
|
||||
|
||||
No matter which MockMvc builder you use, all `MockMvcBuilder` implementations provide
|
|
@ -0,0 +1,100 @@
|
|||
[[mockmvc-setup]]
|
||||
= Configuring MockMvc
|
||||
|
||||
MockMvc can be setup in one of two ways. One is to point directly to the controllers you
|
||||
want to test and programmatically configure Spring MVC infrastructure. The second is to
|
||||
point to Spring configuration with Spring MVC and controller infrastructure in it.
|
||||
|
||||
TIP: For a comparison of those two modes, check xref:testing/mockmvc/setup-options.adoc[Setup Options].
|
||||
|
||||
To set up MockMvc for testing a specific controller, use the following:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
----
|
||||
class MyWebTests {
|
||||
|
||||
MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
----
|
||||
class MyWebTests {
|
||||
|
||||
lateinit var mockMvc : MockMvc
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(AccountController()).build()
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
Or you can also use this setup when testing through the
|
||||
xref:testing/webtestclient.adoc#webtestclient-controller-config[WebTestClient] which delegates to the same builder
|
||||
as shown above.
|
||||
|
||||
To set up MockMvc through Spring configuration, use the following:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
----
|
||||
@SpringJUnitWebConfig(locations = "my-servlet-context.xml")
|
||||
class MyWebTests {
|
||||
|
||||
MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup(WebApplicationContext wac) {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
----
|
||||
@SpringJUnitWebConfig(locations = ["my-servlet-context.xml"])
|
||||
class MyWebTests {
|
||||
|
||||
lateinit var mockMvc: MockMvc
|
||||
|
||||
@BeforeEach
|
||||
fun setup(wac: WebApplicationContext) {
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
Or you can also use this setup when testing through the
|
||||
xref:testing/webtestclient.adoc#webtestclient-context-config[WebTestClient] which delegates to the same builder
|
||||
as shown above.
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server-static-imports]]
|
||||
[[mockmvc-server-static-imports]]
|
||||
= Static Imports
|
||||
:page-section-summary-toc: 1
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-vs-streaming-response]]
|
||||
[[mockmvc-vs-streaming-response]]
|
||||
= Streaming Responses
|
||||
|
||||
You can use `WebTestClient` to test xref:testing/webtestclient.adoc#webtestclient-stream[streaming responses]
|
|
@ -1,8 +1,8 @@
|
|||
[[spring-mvc-test-server-htmlunit]]
|
||||
[[mockmvc-server-htmlunit]]
|
||||
= HtmlUnit Integration
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
Spring provides integration between xref:testing/spring-mvc-test-framework/server.adoc[MockMvc] and
|
||||
Spring provides integration between xref:testing/mockmvc/overview.adoc[MockMvc] and
|
||||
https://htmlunit.sourceforge.io/[HtmlUnit]. This simplifies performing end-to-end testing
|
||||
when using HTML-based views. This integration lets you:
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
[[spring-mvc-test-server-htmlunit-geb]]
|
||||
[[mockmvc-server-htmlunit-geb]]
|
||||
= MockMvc and Geb
|
||||
|
||||
In the previous section, we saw how to use MockMvc with WebDriver. In this section, we
|
||||
use https://www.gebish.org/[Geb] to make our tests even Groovy-er.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-geb-why]]
|
||||
[[mockmvc-server-htmlunit-geb-why]]
|
||||
== Why Geb and MockMvc?
|
||||
|
||||
Geb is backed by WebDriver, so it offers many of the
|
||||
xref:testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-why[same benefits] that we get from
|
||||
xref:testing/mockmvc/htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-why[same benefits] that we get from
|
||||
WebDriver. However, Geb makes things even easier by taking care of some of the
|
||||
boilerplate code for us.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-geb-setup]]
|
||||
[[mockmvc-server-htmlunit-geb-setup]]
|
||||
== MockMvc and Geb Setup
|
||||
|
||||
We can easily initialize a Geb `Browser` with a Selenium WebDriver that uses MockMvc, as
|
||||
|
@ -28,14 +28,14 @@ def setup() {
|
|||
----
|
||||
|
||||
NOTE: This is a simple example of using `MockMvcHtmlUnitDriverBuilder`. For more advanced
|
||||
usage, see xref:testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-advanced-builder[Advanced `MockMvcHtmlUnitDriverBuilder`].
|
||||
usage, see xref:testing/mockmvc/htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-advanced-builder[Advanced `MockMvcHtmlUnitDriverBuilder`].
|
||||
|
||||
This ensures that any URL referencing `localhost` as the server is directed to our
|
||||
`MockMvc` instance without the need for a real HTTP connection. Any other URL is
|
||||
requested by using a network connection as normal. This lets us easily test the use of
|
||||
CDNs.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-geb-usage]]
|
||||
[[mockmvc-server-htmlunit-geb-usage]]
|
||||
== MockMvc and Geb Usage
|
||||
|
||||
Now we can use Geb as we normally would but without the need to deploy our application to
|
||||
|
@ -62,7 +62,7 @@ forwarded to the current page object. This removes a lot of the boilerplate code
|
|||
needed when using WebDriver directly.
|
||||
|
||||
As with direct WebDriver usage, this improves on the design of our
|
||||
xref:testing/spring-mvc-test-framework/server-htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-usage[HtmlUnit test] by using the Page Object
|
||||
xref:testing/mockmvc/htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-usage[HtmlUnit test] by using the Page Object
|
||||
Pattern. As mentioned previously, we can use the Page Object Pattern with HtmlUnit and
|
||||
WebDriver, but it is even easier with Geb. Consider our new Groovy-based
|
||||
`CreateMessagePage` implementation:
|
|
@ -1,10 +1,10 @@
|
|||
[[spring-mvc-test-server-htmlunit-mah]]
|
||||
[[mockmvc-server-htmlunit-mah]]
|
||||
= MockMvc and HtmlUnit
|
||||
|
||||
This section describes how to integrate MockMvc and HtmlUnit. Use this option if you want
|
||||
to use the raw HtmlUnit libraries.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-mah-setup]]
|
||||
[[mockmvc-server-htmlunit-mah-setup]]
|
||||
== MockMvc and HtmlUnit Setup
|
||||
|
||||
First, make sure that you have included a test dependency on
|
||||
|
@ -45,14 +45,14 @@ Kotlin::
|
|||
======
|
||||
|
||||
NOTE: This is a simple example of using `MockMvcWebClientBuilder`. For advanced usage,
|
||||
see xref:testing/spring-mvc-test-framework/server-htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-advanced-builder[Advanced `MockMvcWebClientBuilder`].
|
||||
see xref:testing/mockmvc/htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-advanced-builder[Advanced `MockMvcWebClientBuilder`].
|
||||
|
||||
This ensures that any URL that references `localhost` as the server is directed to our
|
||||
`MockMvc` instance without the need for a real HTTP connection. Any other URL is
|
||||
requested by using a network connection, as normal. This lets us easily test the use of
|
||||
CDNs.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-mah-usage]]
|
||||
[[mockmvc-server-htmlunit-mah-usage]]
|
||||
== MockMvc and HtmlUnit Usage
|
||||
|
||||
Now we can use HtmlUnit as we normally would but without the need to deploy our
|
||||
|
@ -77,7 +77,7 @@ Kotlin::
|
|||
======
|
||||
|
||||
NOTE: The default context path is `""`. Alternatively, we can specify the context path,
|
||||
as described in xref:testing/spring-mvc-test-framework/server-htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-advanced-builder[Advanced `MockMvcWebClientBuilder`].
|
||||
as described in xref:testing/mockmvc/htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-advanced-builder[Advanced `MockMvcWebClientBuilder`].
|
||||
|
||||
Once we have a reference to the `HtmlPage`, we can then fill out the form and submit it
|
||||
to create a message, as the following example shows:
|
||||
|
@ -144,7 +144,7 @@ Kotlin::
|
|||
======
|
||||
|
||||
The preceding code improves on our
|
||||
xref:testing/spring-mvc-test-framework/server-htmlunit/why.adoc#spring-mvc-test-server-htmlunit-mock-mvc-test[MockMvc test] in a number of ways.
|
||||
xref:testing/mockmvc/htmlunit/why.adoc#spring-mvc-test-server-htmlunit-mock-mvc-test[MockMvc test] in a number of ways.
|
||||
First, we no longer have to explicitly verify our form and then create a request that
|
||||
looks like the form. Instead, we request the form, fill it out, and submit it, thereby
|
||||
significantly reducing the overhead.
|
||||
|
@ -156,7 +156,7 @@ the behavior of JavaScript within our pages.
|
|||
See the https://htmlunit.sourceforge.io/gettingStarted.html[HtmlUnit documentation] for
|
||||
additional information about using HtmlUnit.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-mah-advanced-builder]]
|
||||
[[mockmvc-server-htmlunit-mah-advanced-builder]]
|
||||
== Advanced `MockMvcWebClientBuilder`
|
||||
|
||||
In the examples so far, we have used `MockMvcWebClientBuilder` in the simplest way
|
||||
|
@ -275,5 +275,5 @@ This is more verbose, but, by building the `WebClient` with a `MockMvc` instance
|
|||
the full power of MockMvc at our fingertips.
|
||||
|
||||
TIP: For additional information on creating a `MockMvc` instance, see
|
||||
xref:testing/spring-mvc-test-framework/server-setup-options.adoc[Setup Choices].
|
||||
xref:testing/mockmvc/hamcrest/setup.adoc[Configuring MockMvc].
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
[[spring-mvc-test-server-htmlunit-webdriver]]
|
||||
[[mockmvc-server-htmlunit-webdriver]]
|
||||
= MockMvc and WebDriver
|
||||
|
||||
In the previous sections, we have seen how to use MockMvc in conjunction with the raw
|
||||
HtmlUnit APIs. In this section, we use additional abstractions within the Selenium
|
||||
https://docs.seleniumhq.org/projects/webdriver/[WebDriver] to make things even easier.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-webdriver-why]]
|
||||
[[mockmvc-server-htmlunit-webdriver-why]]
|
||||
== Why WebDriver and MockMvc?
|
||||
|
||||
We can already use HtmlUnit and MockMvc, so why would we want to use WebDriver? The
|
||||
|
@ -162,11 +162,11 @@ https://github.com/SeleniumHQ/selenium/wiki/PageObjects[Page Object Pattern]. Wh
|
|||
can certainly do this with HtmlUnit, WebDriver provides some tools that we explore in the
|
||||
following sections to make this pattern much easier to implement.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-webdriver-setup]]
|
||||
[[mockmvc-server-htmlunit-webdriver-setup]]
|
||||
== MockMvc and WebDriver Setup
|
||||
|
||||
To use Selenium WebDriver with the Spring MVC Test framework, make sure that your project
|
||||
includes a test dependency on `org.seleniumhq.selenium:selenium-htmlunit3-driver`.
|
||||
To use Selenium WebDriver with `MockMvc`, make sure that your project includes a test
|
||||
dependency on `org.seleniumhq.selenium:selenium-htmlunit3-driver`.
|
||||
|
||||
We can easily create a Selenium WebDriver that integrates with MockMvc by using the
|
||||
`MockMvcHtmlUnitDriverBuilder` as the following example shows:
|
||||
|
@ -203,14 +203,14 @@ Kotlin::
|
|||
======
|
||||
|
||||
NOTE: This is a simple example of using `MockMvcHtmlUnitDriverBuilder`. For more advanced
|
||||
usage, see xref:testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-advanced-builder[Advanced `MockMvcHtmlUnitDriverBuilder`].
|
||||
usage, see xref:testing/mockmvc/htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-advanced-builder[Advanced `MockMvcHtmlUnitDriverBuilder`].
|
||||
|
||||
The preceding example ensures that any URL that references `localhost` as the server is
|
||||
directed to our `MockMvc` instance without the need for a real HTTP connection. Any other
|
||||
URL is requested by using a network connection, as normal. This lets us easily test the
|
||||
use of CDNs.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-webdriver-usage]]
|
||||
[[mockmvc-server-htmlunit-webdriver-usage]]
|
||||
== MockMvc and WebDriver Usage
|
||||
|
||||
Now we can use WebDriver as we normally would but without the need to deploy our
|
||||
|
@ -259,9 +259,9 @@ Kotlin::
|
|||
======
|
||||
--
|
||||
|
||||
This improves on the design of our xref:testing/spring-mvc-test-framework/server-htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-usage[HtmlUnit test]
|
||||
This improves on the design of our xref:testing/mockmvc/htmlunit/mah.adoc#spring-mvc-test-server-htmlunit-mah-usage[HtmlUnit test]
|
||||
by leveraging the Page Object Pattern. As we mentioned in
|
||||
xref:testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-why[Why WebDriver and MockMvc?], we can use the Page Object Pattern
|
||||
xref:testing/mockmvc/htmlunit/webdriver.adoc#spring-mvc-test-server-htmlunit-webdriver-why[Why WebDriver and MockMvc?], we can use the Page Object Pattern
|
||||
with HtmlUnit, but it is much easier with WebDriver. Consider the following
|
||||
`CreateMessagePage` implementation:
|
||||
|
||||
|
@ -451,7 +451,7 @@ Kotlin::
|
|||
For additional information on using WebDriver, see the Selenium
|
||||
https://github.com/SeleniumHQ/selenium/wiki/Getting-Started[WebDriver documentation].
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-webdriver-advanced-builder]]
|
||||
[[mockmvc-server-htmlunit-webdriver-advanced-builder]]
|
||||
== Advanced `MockMvcHtmlUnitDriverBuilder`
|
||||
|
||||
In the examples so far, we have used `MockMvcHtmlUnitDriverBuilder` in the simplest way
|
||||
|
@ -570,5 +570,5 @@ This is more verbose, but, by building the `WebDriver` with a `MockMvc` instance
|
|||
the full power of MockMvc at our fingertips.
|
||||
|
||||
TIP: For additional information on creating a `MockMvc` instance, see
|
||||
xref:testing/spring-mvc-test-framework/server-setup-options.adoc[Setup Choices].
|
||||
xref:testing/mockmvc/hamcrest/setup.adoc[Configuring MockMvc].
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server-htmlunit-why]]
|
||||
[[mockmvc-server-htmlunit-why]]
|
||||
= Why HtmlUnit Integration?
|
||||
|
||||
The most obvious question that comes to mind is "`Why do I need this?`" The answer is
|
||||
|
@ -94,7 +94,7 @@ follows:
|
|||
======
|
||||
Java::
|
||||
+
|
||||
[[spring-mvc-test-server-htmlunit-mock-mvc-test]]
|
||||
[[mockmvc-server-htmlunit-mock-mvc-test]]
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
----
|
||||
String summaryParamName = "summary";
|
||||
|
@ -151,7 +151,7 @@ the input to a user for creating a message. In addition, our form view can poten
|
|||
use additional resources that impact the behavior of the page, such as JavaScript
|
||||
validation.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-why-integration]]
|
||||
[[mockmvc-server-htmlunit-why-integration]]
|
||||
== Integration Testing to the Rescue?
|
||||
|
||||
To resolve the issues mentioned earlier, we could perform end-to-end integration testing,
|
||||
|
@ -181,23 +181,23 @@ and without side effects. We can then implement a small number of true end-to-en
|
|||
integration tests that validate simple workflows to ensure that everything works together
|
||||
properly.
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-why-mockmvc]]
|
||||
[[mockmvc-server-htmlunit-why-mockmvc]]
|
||||
== Enter HtmlUnit Integration
|
||||
|
||||
So how can we achieve a balance between testing the interactions of our pages and still
|
||||
retain good performance within our test suite? The answer is: "`By integrating MockMvc
|
||||
with HtmlUnit.`"
|
||||
|
||||
[[spring-mvc-test-server-htmlunit-options]]
|
||||
[[mockmvc-server-htmlunit-options]]
|
||||
== HtmlUnit Integration Options
|
||||
|
||||
You have a number of options when you want to integrate MockMvc with HtmlUnit:
|
||||
|
||||
* xref:testing/spring-mvc-test-framework/server-htmlunit/mah.adoc[MockMvc and HtmlUnit]: Use this option if you
|
||||
* xref:testing/mockmvc/htmlunit/mah.adoc[MockMvc and HtmlUnit]: Use this option if you
|
||||
want to use the raw HtmlUnit libraries.
|
||||
* xref:testing/spring-mvc-test-framework/server-htmlunit/webdriver.adoc[MockMvc and WebDriver]: Use this option to
|
||||
* xref:testing/mockmvc/htmlunit/webdriver.adoc[MockMvc and WebDriver]: Use this option to
|
||||
ease development and reuse code between integration and end-to-end testing.
|
||||
* xref:testing/spring-mvc-test-framework/server-htmlunit/geb.adoc[MockMvc and Geb]: Use this option if you want to
|
||||
* xref:testing/mockmvc/htmlunit/geb.adoc[MockMvc and Geb]: Use this option if you want to
|
||||
use Groovy for testing, ease development, and reuse code between integration and
|
||||
end-to-end testing.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server]]
|
||||
[[mockmvc-overview]]
|
||||
= Overview
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
|
@ -8,17 +8,17 @@ mappings, data binding, message conversion, type conversion, validation, and nor
|
|||
do they involve any of the supporting `@InitBinder`, `@ModelAttribute`, or
|
||||
`@ExceptionHandler` methods.
|
||||
|
||||
The Spring MVC Test framework, also known as `MockMvc`, aims to provide more complete
|
||||
testing for Spring MVC controllers without a running server. It does that by invoking
|
||||
the `DispatcherServlet` and passing
|
||||
`MockMvc` aims to provide more complete testing for Spring MVC controllers without a
|
||||
running server. It does that by invoking the `DispatcherServlet` and passing
|
||||
xref:testing/unit.adoc#mock-objects-servlet["`mock`" implementations of the Servlet API] from the
|
||||
`spring-test` module which replicates the full Spring MVC request handling without
|
||||
a running server.
|
||||
|
||||
MockMvc is a server side test framework that lets you verify most of the functionality
|
||||
of a Spring MVC application using lightweight and targeted tests. You can use it on
|
||||
its own to perform requests and to verify responses, or you can also use it through
|
||||
the xref:testing/webtestclient.adoc[WebTestClient] API with MockMvc plugged in as the server to handle requests
|
||||
with.
|
||||
its own to perform requests and to verify responses using Hamcrest, or through
|
||||
`MockMvcTester` that provides a fluent API using AssertJ. Finally, you can also use it
|
||||
through the xref:testing/webtestclient.adoc[WebTestClient] API with MockMvc plugged in
|
||||
as the server to handle requests with.
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-server-resources]]
|
||||
[[mockmvc-server-resources]]
|
||||
= Further Examples
|
||||
:page-section-summary-toc: 1
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
[[mockmvc-server-setup-options]]
|
||||
= Setup Options
|
||||
|
||||
MockMvc can be setup in one of two ways. One is to point directly to the controllers you
|
||||
want to test and programmatically configure Spring MVC infrastructure. The second is to
|
||||
point to Spring configuration with Spring MVC and controller infrastructure in it.
|
||||
|
||||
Which setup option should you use?
|
||||
|
||||
The use of an `ApplicationContext` loads your actual Spring MVC configuration, resulting
|
||||
The `WebApplicationContext`-based test loads your actual Spring MVC configuration,
|
||||
resulting in a more complete integration test. Since the TestContext framework caches
|
||||
the loaded Spring configuration, it helps keep tests running fast, even as you introduce
|
||||
more tests in your test suite using the same configuration. Furthermore, you can
|
||||
override services used by your controller using `@MockitoBean` to remain focused on
|
||||
testing the web layer.
|
||||
|
||||
The standalone test, on the other hand, is a little closer to a unit test. It tests one
|
||||
controller at a time. You can manually inject the controller with mock dependencies, and
|
||||
it does not involve loading Spring configuration. Such tests are more focused on style
|
||||
and make it easier to see which controller is being tested, whether any specific Spring
|
||||
MVC configuration is required to work, and so on. The standalone setup is also a very
|
||||
convenient way to write ad-hoc tests to verify specific behavior or to debug an issue.
|
||||
|
||||
As with most "`integration versus unit testing`" debates, there is no right or wrong
|
||||
answer. However, using standalone tests does imply the need for additional integration
|
||||
tests to verify your Spring MVC configuration. Alternatively, you can write all your
|
||||
tests with a `WebApplicationContext`, so that they always test against your actual Spring
|
||||
MVC configuration.
|
|
@ -1,4 +1,4 @@
|
|||
[[spring-mvc-test-vs-end-to-end-integration-tests]]
|
||||
[[mockmvc-vs-end-to-end-integration-tests]]
|
||||
= MockMvc vs End-to-End Tests
|
||||
|
||||
MockMvc is built on Servlet API mock implementations from the
|
|
@ -1,15 +0,0 @@
|
|||
[[spring-mvc-test-framework]]
|
||||
= MockMvc
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The Spring MVC Test framework, also known as MockMvc, provides support for testing Spring
|
||||
MVC applications. It performs full Spring MVC request handling but via mock request and
|
||||
response objects instead of a running server.
|
||||
|
||||
MockMvc can be used on its own to perform requests and verify responses. It can also be
|
||||
used through the xref:testing/webtestclient.adoc[WebTestClient] where MockMvc is plugged in as the server to handle
|
||||
requests with. The advantage of `WebTestClient` is the option to work with higher level
|
||||
objects instead of raw data as well as the ability to switch to full, end-to-end HTTP
|
||||
tests against a live server and use the same test API.
|
||||
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
[[spring-mvc-test-server-setup-options]]
|
||||
= Setup Choices
|
||||
|
||||
MockMvc can be setup in one of two ways. One is to point directly to the controllers you
|
||||
want to test and programmatically configure Spring MVC infrastructure. The second is to
|
||||
point to Spring configuration with Spring MVC and controller infrastructure in it.
|
||||
|
||||
To set up MockMvc for testing a specific controller, use the following:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
----
|
||||
class MyWebTests {
|
||||
|
||||
MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
----
|
||||
class MyWebTests {
|
||||
|
||||
lateinit var mockMvc : MockMvc
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(AccountController()).build()
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
Or you can also use this setup when testing through the
|
||||
xref:testing/webtestclient.adoc#webtestclient-controller-config[WebTestClient] which delegates to the same builder
|
||||
as shown above.
|
||||
|
||||
To set up MockMvc through Spring configuration, use the following:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
----
|
||||
@SpringJUnitWebConfig(locations = "my-servlet-context.xml")
|
||||
class MyWebTests {
|
||||
|
||||
MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup(WebApplicationContext wac) {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
----
|
||||
@SpringJUnitWebConfig(locations = ["my-servlet-context.xml"])
|
||||
class MyWebTests {
|
||||
|
||||
lateinit var mockMvc: MockMvc
|
||||
|
||||
@BeforeEach
|
||||
fun setup(wac: WebApplicationContext) {
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
Or you can also use this setup when testing through the
|
||||
xref:testing/webtestclient.adoc#webtestclient-context-config[WebTestClient] which delegates to the same builder
|
||||
as shown above.
|
||||
|
||||
|
||||
|
||||
Which setup option should you use?
|
||||
|
||||
The `webAppContextSetup` loads your actual Spring MVC configuration, resulting in a more
|
||||
complete integration test. Since the TestContext framework caches the loaded Spring
|
||||
configuration, it helps keep tests running fast, even as you introduce more tests in your
|
||||
test suite. Furthermore, you can inject mock services into controllers through Spring
|
||||
configuration to remain focused on testing the web layer. The following example declares
|
||||
a mock service with Mockito:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<bean id="accountService" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg type="java.lang.Class" value="org.example.AccountService"/>
|
||||
<constructor-arg type="java.lang.String" value="accountService"/>
|
||||
</bean>
|
||||
----
|
||||
|
||||
You can then inject the mock service into the test to set up and verify your
|
||||
expectations, as the following example shows:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||
----
|
||||
@SpringJUnitWebConfig(locations = "test-servlet-context.xml")
|
||||
class AccountTests {
|
||||
|
||||
@Autowired
|
||||
AccountService accountService;
|
||||
|
||||
MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup(WebApplicationContext wac) {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||
----
|
||||
@SpringJUnitWebConfig(locations = ["test-servlet-context.xml"])
|
||||
class AccountTests {
|
||||
|
||||
@Autowired
|
||||
lateinit var accountService: AccountService
|
||||
|
||||
lateinit var mockMvc: MockMvc
|
||||
|
||||
@BeforeEach
|
||||
fun setup(wac: WebApplicationContext) {
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
The `standaloneSetup`, on the other hand, is a little closer to a unit test. It tests one
|
||||
controller at a time. You can manually inject the controller with mock dependencies, and
|
||||
it does not involve loading Spring configuration. Such tests are more focused on style
|
||||
and make it easier to see which controller is being tested, whether any specific Spring
|
||||
MVC configuration is required to work, and so on. The `standaloneSetup` is also a very
|
||||
convenient way to write ad-hoc tests to verify specific behavior or to debug an issue.
|
||||
|
||||
As with most "`integration versus unit testing`" debates, there is no right or wrong
|
||||
answer. However, using the `standaloneSetup` does imply the need for additional
|
||||
`webAppContextSetup` tests in order to verify your Spring MVC configuration.
|
||||
Alternatively, you can write all your tests with `webAppContextSetup`, in order to always
|
||||
test against your actual Spring MVC configuration.
|
||||
|
|
@ -68,8 +68,8 @@ or alternative Servlet API mock objects (such as http://www.mockobjects.com[Mock
|
|||
TIP: Since Spring Framework 6.0, the mock objects in `org.springframework.mock.web` are
|
||||
based on the Servlet 6.0 API.
|
||||
|
||||
The Spring MVC Test framework builds on the mock Servlet API objects to provide an
|
||||
integration testing framework for Spring MVC. See xref:testing/spring-mvc-test-framework.adoc[MockMvc].
|
||||
MockMvc builds on the mock Servlet API objects to provide an integration testing
|
||||
framework for Spring MVC. See xref:testing/mockmvc.adoc[MockMvc].
|
||||
|
||||
|
||||
[[mock-objects-web-reactive]]
|
||||
|
@ -165,4 +165,4 @@ combined with `MockHttpServletRequest`, `MockHttpSession`, and so on from Spring
|
|||
xref:testing/unit.adoc#mock-objects-servlet[Servlet API mocks]. For thorough integration testing of your
|
||||
Spring MVC and REST `Controller` classes in conjunction with your `WebApplicationContext`
|
||||
configuration for Spring MVC, use the
|
||||
xref:testing/spring-mvc-test-framework.adoc[Spring MVC Test Framework] instead.
|
||||
xref:testing/mockmvc.adoc[MockMvc] instead.
|
||||
|
|
|
@ -51,7 +51,7 @@ For Spring MVC, use the following which delegates to the
|
|||
{spring-framework-api}/test/web/servlet/setup/StandaloneMockMvcBuilder.html[StandaloneMockMvcBuilder]
|
||||
to load infrastructure equivalent to the xref:web/webmvc/mvc-config.adoc[WebMvc Java config],
|
||||
registers the given controller(s), and creates an instance of
|
||||
xref:testing/spring-mvc-test-framework.adoc[MockMvc] to handle requests:
|
||||
xref:testing/mockmvc.adoc[MockMvc] to handle requests:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
|
@ -128,7 +128,7 @@ Kotlin::
|
|||
|
||||
For Spring MVC, use the following where the Spring `ApplicationContext` is passed to
|
||||
{spring-framework-api}/test/web/servlet/setup/MockMvcBuilders.html#webAppContextSetup-org.springframework.web.context.WebApplicationContext-[MockMvcBuilders.webAppContextSetup]
|
||||
to create a xref:testing/spring-mvc-test-framework.adoc[MockMvc] instance to handle
|
||||
to create a xref:testing/mockmvc.adoc[MockMvc] instance to handle
|
||||
requests:
|
||||
|
||||
[tabs]
|
||||
|
|
|
@ -16,7 +16,7 @@ See xref:testing/testcontext-framework.adoc[TestContext Framework] for more deta
|
|||
* Spring MVC Test: A framework, also known as `MockMvc`, for testing annotated controllers
|
||||
through the `DispatcherServlet` (that is, supporting annotations), complete with the
|
||||
Spring MVC infrastructure but without an HTTP server.
|
||||
See xref:testing/spring-mvc-test-framework.adoc[Spring MVC Test] for more details.
|
||||
See xref:testing/mockmvc.adoc[Spring MVC Test] for more details.
|
||||
|
||||
* Client-side REST: `spring-test` provides a `MockRestServiceServer` that you can use as
|
||||
a mock server for testing client-side code that internally uses the `RestTemplate`.
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterassertions;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class HotelControllerTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new HotelController());
|
||||
|
||||
|
||||
void getHotel() {
|
||||
// tag::get[]
|
||||
assertThat(mockMvc.get().uri("/hotels/{id}", 42))
|
||||
.hasStatusOk()
|
||||
.hasContentTypeCompatibleWith(MediaType.APPLICATION_JSON)
|
||||
.bodyJson().isLenientlyEqualTo("sample/hotel-42.json");
|
||||
// end::get[]
|
||||
}
|
||||
|
||||
|
||||
void getHotelInvalid() {
|
||||
// tag::failure[]
|
||||
assertThat(mockMvc.get().uri("/hotels/{id}", -1))
|
||||
.hasFailed()
|
||||
.hasStatus(HttpStatus.BAD_REQUEST)
|
||||
.failure().hasMessageContaining("Identifier should be positive");
|
||||
// end::failure[]
|
||||
}
|
||||
|
||||
static class HotelController {}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterassertionsjson;
|
||||
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
class FamilyControllerTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new FamilyController());
|
||||
|
||||
|
||||
void extractingPathAsMap() {
|
||||
// tag::extract-asmap[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.extractingPath("$.members[0]")
|
||||
.asMap()
|
||||
.contains(entry("name", "Homer"));
|
||||
// end::extract-asmap[]
|
||||
}
|
||||
|
||||
void extractingPathAndConvertWithType() {
|
||||
// tag::extract-convert[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.extractingPath("$.members[0]")
|
||||
.convertTo(Member.class)
|
||||
.satisfies(member -> assertThat(member.name).isEqualTo("Homer"));
|
||||
// end::extract-convert[]
|
||||
}
|
||||
|
||||
void extractingPathAndConvertWithAssertFactory() {
|
||||
// tag::extract-convert-assert-factory[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.extractingPath("$.members")
|
||||
.convertTo(InstanceOfAssertFactories.list(Member.class))
|
||||
.hasSize(5)
|
||||
.element(0).satisfies(member -> assertThat(member.name).isEqualTo("Homer"));
|
||||
// end::extract-convert-assert-factory[]
|
||||
}
|
||||
|
||||
void assertTheSimpsons() {
|
||||
// tag::assert-file[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.isStrictlyEqualTo("sample/simpsons.json");
|
||||
// end::assert-file[]
|
||||
}
|
||||
|
||||
static class FamilyController {}
|
||||
|
||||
record Member(String name) {}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterintegration;
|
||||
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
public class HotelControllerTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new HotelController());
|
||||
|
||||
|
||||
void perform() {
|
||||
// tag::perform[]
|
||||
// Static import on MockMvcRequestBuilders.get
|
||||
assertThat(mockMvc.perform(get("/hotels/{id}", 42)))
|
||||
.hasStatusOk();
|
||||
// end::perform[]
|
||||
}
|
||||
|
||||
void performWithCustomMatcher() {
|
||||
// tag::matches[]
|
||||
// Static import on MockMvcResultMatchers.status
|
||||
assertThat(mockMvc.get().uri("/hotels/{id}", 42))
|
||||
.matches(status().isOk());
|
||||
// end::matches[]
|
||||
}
|
||||
|
||||
static class HotelController {}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequests;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
import org.springframework.test.web.servlet.assertj.MvcTestResult;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class HotelControllerTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new HotelController());
|
||||
|
||||
|
||||
void createHotel() {
|
||||
// tag::post[]
|
||||
assertThat(mockMvc.post().uri("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON))
|
||||
. // ...
|
||||
// end::post[]
|
||||
hasStatusOk();
|
||||
}
|
||||
|
||||
void createHotelMultipleAssertions() {
|
||||
// tag::post-exchange[]
|
||||
MvcTestResult result = mockMvc.post().uri("/hotels/{id}", 42)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange();
|
||||
assertThat(result). // ...
|
||||
// end::post-exchange[]
|
||||
hasStatusOk();
|
||||
}
|
||||
|
||||
void queryParameters() {
|
||||
// tag::query-parameters[]
|
||||
assertThat(mockMvc.get().uri("/hotels?thing={thing}", "somewhere"))
|
||||
. // ...
|
||||
// end::query-parameters[]
|
||||
hasStatusOk();
|
||||
}
|
||||
|
||||
void parameters() {
|
||||
// tag::parameters[]
|
||||
assertThat(mockMvc.get().uri("/hotels").param("thing", "somewhere"))
|
||||
. // ...
|
||||
// end::parameters[]
|
||||
hasStatusOk();
|
||||
}
|
||||
|
||||
static class HotelController {}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequestsasync;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AsyncControllerTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new AsyncController());
|
||||
|
||||
void asyncExchangeWithCustomTimeToWait() {
|
||||
// tag::duration[]
|
||||
assertThat(mockMvc.get().uri("/compute").exchange(Duration.ofSeconds(5)))
|
||||
. // ...
|
||||
// end::duration[]
|
||||
hasStatusOk();
|
||||
}
|
||||
|
||||
static class AsyncController {}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequestsmultipart;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class MultipartControllerTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new MultipartController());
|
||||
|
||||
void multiPart() {
|
||||
// tag::snippet[]
|
||||
assertThat(mockMvc.post().uri("/upload").multipart()
|
||||
.file("file1.txt", "Hello".getBytes(StandardCharsets.UTF_8))
|
||||
.file("file2.txt", "World".getBytes(StandardCharsets.UTF_8)))
|
||||
. // ...
|
||||
// end::snippet[]
|
||||
hasStatusOk();
|
||||
}
|
||||
|
||||
static class MultipartController {}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequestspaths;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class HotelControllerTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new HotelController());
|
||||
|
||||
void contextAndServletPaths() {
|
||||
// tag::context-servlet-paths[]
|
||||
assertThat(mockMvc.get().uri("/app/main/hotels/{id}", 42)
|
||||
.contextPath("/app").servletPath("/main"))
|
||||
. // ...
|
||||
// end::context-servlet-paths[]
|
||||
hasStatusOk();
|
||||
}
|
||||
|
||||
void configureMockMvcTesterWithDefaultSettings() {
|
||||
// tag::default-customizations[]
|
||||
MockMvcTester mockMvc = MockMvcTester.of(List.of(new HotelController()),
|
||||
builder -> builder.defaultRequest(get("/")
|
||||
.contextPath("/app").servletPath("/main")
|
||||
.accept(MediaType.APPLICATION_JSON)).build());
|
||||
// end::default-customizations[]
|
||||
}
|
||||
|
||||
|
||||
static class HotelController {}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class AccountController {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
// tag::snippet[]
|
||||
@SpringJUnitWebConfig(ApplicationWebConfiguration.class)
|
||||
class AccountControllerIntegrationTests {
|
||||
|
||||
private final MockMvcTester mockMvc;
|
||||
|
||||
AccountControllerIntegrationTests(@Autowired WebApplicationContext wac) {
|
||||
this.mockMvc = MockMvcTester.from(wac);
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
// end::snippet[]
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup;
|
||||
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
|
||||
// tag::snippet[]
|
||||
public class AccountControllerStandaloneTests {
|
||||
|
||||
private final MockMvcTester mockMvc = MockMvcTester.of(new AccountController());
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
// end::snippet[]
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class ApplicationWebConfiguration {
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup.converter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup.ApplicationWebConfiguration;
|
||||
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
|
||||
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
// tag::snippet[]
|
||||
@SpringJUnitWebConfig(ApplicationWebConfiguration.class)
|
||||
class AccountControllerIntegrationTests {
|
||||
|
||||
private final MockMvcTester mockMvc;
|
||||
|
||||
AccountControllerIntegrationTests(@Autowired WebApplicationContext wac) {
|
||||
this.mockMvc = MockMvcTester.from(wac).withHttpMessageConverters(
|
||||
List.of(wac.getBean(AbstractJackson2HttpMessageConverter.class)));
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
// end::snippet[]
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterassertions
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
|
||||
class HotelControllerTests {
|
||||
|
||||
private val mockMvc = MockMvcTester.of(HotelController())
|
||||
|
||||
fun getHotel() {
|
||||
// tag::get[]
|
||||
assertThat(mockMvc.get().uri("/hotels/{id}", 42))
|
||||
.hasStatusOk()
|
||||
.hasContentTypeCompatibleWith(MediaType.APPLICATION_JSON)
|
||||
.bodyJson().isLenientlyEqualTo("sample/hotel-42.json")
|
||||
// end::get[]
|
||||
}
|
||||
|
||||
|
||||
fun getHotelInvalid() {
|
||||
// tag::failure[]
|
||||
assertThat(mockMvc.get().uri("/hotels/{id}", -1))
|
||||
.hasFailed()
|
||||
.hasStatus(HttpStatus.BAD_REQUEST)
|
||||
.failure().hasMessageContaining("Identifier should be positive")
|
||||
// end::failure[]
|
||||
}
|
||||
|
||||
class HotelController
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterassertionsjson
|
||||
|
||||
import org.assertj.core.api.Assertions.*
|
||||
import org.assertj.core.api.InstanceOfAssertFactories
|
||||
import org.assertj.core.api.ThrowingConsumer
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class FamilyControllerTests {
|
||||
|
||||
private val mockMvc = MockMvcTester.of(FamilyController())
|
||||
|
||||
|
||||
fun extractingPathAsMap() {
|
||||
// tag::extract-asmap[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.extractingPath("$.members[0]")
|
||||
.asMap()
|
||||
.contains(entry("name", "Homer"))
|
||||
// end::extract-asmap[]
|
||||
}
|
||||
|
||||
fun extractingPathAndConvertWithType() {
|
||||
// tag::extract-convert[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.extractingPath("$.members[0]")
|
||||
.convertTo(Member::class.java)
|
||||
.satisfies(ThrowingConsumer { member: Member ->
|
||||
assertThat(member.name).isEqualTo("Homer")
|
||||
})
|
||||
// end::extract-convert[]
|
||||
}
|
||||
|
||||
fun extractingPathAndConvertWithAssertFactory() {
|
||||
// tag::extract-convert-assert-factory[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.extractingPath("$.members")
|
||||
.convertTo(InstanceOfAssertFactories.list(Member::class.java))
|
||||
.hasSize(5)
|
||||
.element(0).satisfies(ThrowingConsumer { member: Member ->
|
||||
assertThat(member.name).isEqualTo("Homer")
|
||||
})
|
||||
// end::extract-convert-assert-factory[]
|
||||
}
|
||||
|
||||
fun assertTheSimpsons() {
|
||||
// tag::assert-file[]
|
||||
assertThat(mockMvc.get().uri("/family")).bodyJson()
|
||||
.isStrictlyEqualTo("sample/simpsons.json")
|
||||
// end::assert-file[]
|
||||
}
|
||||
|
||||
class FamilyController
|
||||
|
||||
@JvmRecord
|
||||
data class Member(val name: String)
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterintegration
|
||||
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.assertj.core.api.Assertions.*
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class HotelController {
|
||||
|
||||
private val mockMvc = MockMvcTester.of(HotelController())
|
||||
|
||||
|
||||
fun perform() {
|
||||
// tag::perform[]
|
||||
// Static import on MockMvcRequestBuilders.get
|
||||
assertThat(mockMvc.perform(get("/hotels/{id}",42)))
|
||||
.hasStatusOk()
|
||||
// end::perform[]
|
||||
}
|
||||
|
||||
fun performWithCustomMatcher() {
|
||||
// tag::perform[]
|
||||
// Static import on MockMvcResultMatchers.status
|
||||
assertThat(mockMvc.get().uri("/hotels/{id}", 42))
|
||||
.matches(status().isOk())
|
||||
// end::perform[]
|
||||
}
|
||||
|
||||
class HotelController
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequests
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
|
||||
class HotelControllerTests {
|
||||
|
||||
private val mockMvc = MockMvcTester.of(HotelController())
|
||||
|
||||
fun createHotel() {
|
||||
// tag::post[]
|
||||
assertThat(mockMvc.post().uri("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON))
|
||||
. // ...
|
||||
// end::post[]
|
||||
hasStatusOk()
|
||||
}
|
||||
|
||||
fun createHotelMultipleAssertions() {
|
||||
// tag::post-exchange[]
|
||||
val result = mockMvc.post().uri("/hotels/{id}", 42)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange()
|
||||
assertThat(result)
|
||||
. // ...
|
||||
// end::post-exchange[]
|
||||
hasStatusOk()
|
||||
}
|
||||
|
||||
fun queryParameters() {
|
||||
// tag::query-parameters[]
|
||||
assertThat(mockMvc.get().uri("/hotels?thing={thing}", "somewhere"))
|
||||
. // ...
|
||||
//end::query-parameters[]
|
||||
hasStatusOk()
|
||||
}
|
||||
|
||||
fun parameters() {
|
||||
// tag::parameters[]
|
||||
assertThat(mockMvc.get().uri("/hotels").param("thing", "somewhere"))
|
||||
. // ...
|
||||
// end::parameters[]
|
||||
hasStatusOk()
|
||||
}
|
||||
|
||||
class HotelController
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequestsasync
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
import java.time.Duration
|
||||
|
||||
class AsyncControllerTests {
|
||||
|
||||
private val mockMvc = MockMvcTester.of(AsyncController())
|
||||
|
||||
fun asyncExchangeWithCustomTimeToWait() {
|
||||
// tag::duration[]
|
||||
assertThat(mockMvc.get().uri("/compute").exchange(Duration.ofSeconds(5)))
|
||||
. // ...
|
||||
// end::duration[]
|
||||
hasStatusOk()
|
||||
}
|
||||
|
||||
class AsyncController
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequestsmultipart
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class MultipartControllerTests {
|
||||
|
||||
private val mockMvc = MockMvcTester.of(MultipartController())
|
||||
|
||||
fun multiPart() {
|
||||
// tag::snippet[]
|
||||
assertThat(mockMvc.post().uri("/upload").multipart()
|
||||
.file("file1.txt", "Hello".toByteArray(StandardCharsets.UTF_8))
|
||||
.file("file2.txt", "World".toByteArray(StandardCharsets.UTF_8)))
|
||||
. // ...
|
||||
// end::snippet[]
|
||||
hasStatusOk()
|
||||
}
|
||||
|
||||
class MultipartController
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctesterrequestspaths
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
||||
import org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder
|
||||
|
||||
class HotelControllerTests {
|
||||
|
||||
private val mockMvc = MockMvcTester.of(HotelController())
|
||||
|
||||
fun contextAndServletPaths() {
|
||||
// tag::context-servlet-paths[]
|
||||
assertThat(mockMvc.get().uri("/app/main/hotels/{id}", 42)
|
||||
.contextPath("/app").servletPath("/main"))
|
||||
. // ...
|
||||
// end::context-servlet-paths[]
|
||||
hasStatusOk()
|
||||
}
|
||||
|
||||
fun configureMockMvcTesterWithDefaultSettings() {
|
||||
// tag::default-customizations[]
|
||||
val mockMvc =
|
||||
MockMvcTester.of(listOf(HotelController())) { builder: StandaloneMockMvcBuilder ->
|
||||
builder.defaultRequest<StandaloneMockMvcBuilder>(
|
||||
MockMvcRequestBuilders.get("/")
|
||||
.contextPath("/app").servletPath("/main")
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
).build()
|
||||
}
|
||||
// end::default-customizations[]
|
||||
mockMvc.toString() // avoid warning
|
||||
}
|
||||
|
||||
|
||||
class HotelController
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
import org.springframework.web.context.WebApplicationContext
|
||||
|
||||
// tag::snippet[]
|
||||
@SpringJUnitWebConfig(ApplicationWebConfiguration::class)
|
||||
class AccountControllerIntegrationTests(@Autowired wac: WebApplicationContext) {
|
||||
|
||||
private val mockMvc = MockMvcTester.from(wac)
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
// end::snippet[]
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup
|
||||
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
|
||||
// tag::snippet[]
|
||||
class AccountControllerStandaloneTests {
|
||||
|
||||
val mockMvc = MockMvcTester.of(AccountController())
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
// end::snippet[]
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup.converter
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.docs.testing.mockmvc.assertj.mockmvctestersetup.ApplicationWebConfiguration
|
||||
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter
|
||||
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig
|
||||
import org.springframework.test.web.servlet.assertj.MockMvcTester
|
||||
import org.springframework.web.context.WebApplicationContext
|
||||
|
||||
// tag::snippet[]
|
||||
@SpringJUnitWebConfig(ApplicationWebConfiguration::class)
|
||||
class AccountControllerIntegrationTests(@Autowired wac: WebApplicationContext) {
|
||||
|
||||
private val mockMvc = MockMvcTester.from(wac).withHttpMessageConverters(
|
||||
listOf(wac.getBean(AbstractJackson2HttpMessageConverter::class.java)))
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
// end::snippet[]
|
||||
|
Loading…
Reference in New Issue