MockMvc and HtmlUnit
This section describes how to integrate MockMvc and HtmlUnit. Use this option if you want to use the raw HtmlUnit libraries.
MockMvc and HtmlUnit Setup
First, make sure that you have included a test dependency on
org.htmlunit:htmlunit
.
We can easily create an HtmlUnit WebClient
that integrates with MockMvc by using the
MockMvcWebClientBuilder
, as follows:
WebClient webClient;
@BeforeEach
void setup(WebApplicationContext context) {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build();
}
This is a simple example of using MockMvcWebClientBuilder . For advanced usage,
see 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.
MockMvc and HtmlUnit Usage
Now we can use HtmlUnit as we normally would but without the need to deploy our application to a Servlet container. For example, we can request the view to create a message with the following:
HtmlPage createMsgFormPage = webClient.getPage("http://localhost/messages/form");
The default context path is "" . Alternatively, we can specify the context path,
as described in 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:
HtmlForm form = createMsgFormPage.getHtmlElementById("messageForm");
HtmlTextInput summaryInput = createMsgFormPage.getHtmlElementById("summary");
summaryInput.setValueAttribute("Infra Rocks");
HtmlTextArea textInput = createMsgFormPage.getHtmlElementById("text");
textInput.setText("In case you didn't know, Infra Rocks!");
HtmlSubmitInput submit = form.getOneHtmlElementByAttribute("input", "type", "submit");
HtmlPage newMessagePage = submit.click();
Finally, we can verify that a new message was created successfully. The following assertions use the AssertJ library:
assertThat(newMessagePage.getUrl().toString()).endsWith("/messages/123");
String id = newMessagePage.getHtmlElementById("id").getTextContent();
assertThat(id).isEqualTo("123");
String summary = newMessagePage.getHtmlElementById("summary").getTextContent();
assertThat(summary).isEqualTo("Infra Rocks");
String text = newMessagePage.getHtmlElementById("text").getTextContent();
assertThat(text).isEqualTo("In case you didn't know, Infra Rocks!");
The preceding code improves on our 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.
Another important factor is that HtmlUnit uses the Mozilla Rhino engine to evaluate JavaScript. This means that we can also test the behavior of JavaScript within our pages.
See the HtmlUnit documentation for additional information about using HtmlUnit.
Advanced MockMvcWebClientBuilder
In the examples so far, we have used MockMvcWebClientBuilder
in the simplest way
possible, by building a WebClient
based on the WebApplicationContext
loaded for us by
the Infra TestContext Framework. This approach is repeated in the following example:
WebClient webClient;
@BeforeEach
void setup(WebApplicationContext context) {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build();
}
We can also specify additional configuration options, as the following example shows:
WebClient webClient;
@BeforeEach
void setup() {
webClient = MockMvcWebClientBuilder
// demonstrates applying a MockMvcConfigurer (Infra Security)
.webAppContextSetup(context, springSecurity())
// for illustration only - defaults to ""
.contextPath("")
// By default MockMvc is used for localhost only;
// the following will use MockMvc for example.com and example.org as well
.useMockMvcForHosts("example.com","example.org")
.build();
}
As an alternative, we can perform the exact same setup by configuring the MockMvc
instance separately and supplying it to the MockMvcWebClientBuilder
, as follows:
MockMvc mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
webClient = MockMvcWebClientBuilder
.mockMvcSetup(mockMvc)
// for illustration only - defaults to ""
.contextPath("")
// By default MockMvc is used for localhost only;
// the following will use MockMvc for example.com and example.org as well
.useMockMvcForHosts("example.com","example.org")
.build();
This is more verbose, but, by building the WebClient
with a MockMvc
instance, we have
the full power of MockMvc at our fingertips.
For additional information on creating a MockMvc instance, see
Setup Choices.
|