MockMvc and HtmlUnit
本节描述如何集成 MockMvc 和 HtmlUnit。如果您希望使用原始 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
首先,确保已包含对 org.htmlunit:htmlunit
的测试依赖。
First, make sure that you have included a test dependency on
org.htmlunit:htmlunit
.
我们可以使用 MockMvcWebClientBuilder
用 MockMvc 集成的 WebClient
很容易创建 HtmlUnit,如下所示:
We can easily create an HtmlUnit WebClient
that integrates with MockMvc by using the
MockMvcWebClientBuilder
, as follows:
-
Java
-
Kotlin
WebClient webClient;
@BeforeEach
void setup(WebApplicationContext context) {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build();
}
lateinit var webClient: WebClient
@BeforeEach
fun setup(context: WebApplicationContext) {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build()
}
这是一个使用 |
This is a simple example of using |
这确保了将任何引用 localhost
作为服务器的 URL 定向到我们的 MockMvc
实例,而不需要真正的 HTTP 连接。任何其他 URL 都按正常方式使用网络连接请求。这让我们很容易测试 CDN 的使用。
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
现在,我们可以像往常一样使用 HtmlUnit,但不需要将我们的应用程序部署到 Servlet 容器中。例如,我们可以请求视图来用以下方法创建一个消息:
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:
-
Java
-
Kotlin
HtmlPage createMsgFormPage = webClient.getPage("http://localhost/messages/form");
val createMsgFormPage = webClient.getPage("http://localhost/messages/form")
默认上下文路径为 |
The default context path is |
一旦我们引用 HtmlPage
,我们便可以填写表单并提交它来创建一个消息,如下例所示:
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:
-
Java
-
Kotlin
HtmlForm form = createMsgFormPage.getHtmlElementById("messageForm");
HtmlTextInput summaryInput = createMsgFormPage.getHtmlElementById("summary");
summaryInput.setValueAttribute("Spring Rocks");
HtmlTextArea textInput = createMsgFormPage.getHtmlElementById("text");
textInput.setText("In case you didn't know, Spring Rocks!");
HtmlSubmitInput submit = form.getOneHtmlElementByAttribute("input", "type", "submit");
HtmlPage newMessagePage = submit.click();
val form = createMsgFormPage.getHtmlElementById("messageForm")
val summaryInput = createMsgFormPage.getHtmlElementById("summary")
summaryInput.setValueAttribute("Spring Rocks")
val textInput = createMsgFormPage.getHtmlElementById("text")
textInput.setText("In case you didn't know, Spring Rocks!")
val submit = form.getOneHtmlElementByAttribute("input", "type", "submit")
val newMessagePage = submit.click()
最后,我们可以验证是否已成功创建新消息。以下断言使用 AssertJ 库:
Finally, we can verify that a new message was created successfully. The following assertions use the AssertJ library:
-
Java
-
Kotlin
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("Spring Rocks");
String text = newMessagePage.getHtmlElementById("text").getTextContent();
assertThat(text).isEqualTo("In case you didn't know, Spring Rocks!");
assertThat(newMessagePage.getUrl().toString()).endsWith("/messages/123")
val id = newMessagePage.getHtmlElementById("id").getTextContent()
assertThat(id).isEqualTo("123")
val summary = newMessagePage.getHtmlElementById("summary").getTextContent()
assertThat(summary).isEqualTo("Spring Rocks")
val text = newMessagePage.getHtmlElementById("text").getTextContent()
assertThat(text).isEqualTo("In case you didn't know, Spring Rocks!")
前面的代码通过多种方式改进了我们的MockMvc test 。首先,我们不再必须明确验证我们的表单,然后创建一个与该表单相似的请求。相反,我们请求表单、填写它并提交它,从而显著减少了开销。
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.
另一个重要因素是 HtmlUnit uses the Mozilla Rhino engine用于评估 JavaScript。这意味着我们还可以在页面中测试 JavaScript 的行为。
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.
请参阅 HtmlUnit documentation了解更多有关使用 HtmlUnit 的信息。
See the HtmlUnit documentation for additional information about using HtmlUnit.
Advanced MockMvcWebClientBuilder
在迄今为止的示例中,我们已经以最简单的方式使用了 MockMvcWebClientBuilder
,即根据 Spring TestContext 框架为我们加载的 WebApplicationContext
构建一个 WebClient
。以下示例中会重复这种方法:
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 Spring TestContext Framework. This approach is repeated in the following example:
-
Java
-
Kotlin
WebClient webClient;
@BeforeEach
void setup(WebApplicationContext context) {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build();
}
lateinit var webClient: WebClient
@BeforeEach
fun setup(context: WebApplicationContext) {
webClient = MockMvcWebClientBuilder
.webAppContextSetup(context)
.build()
}
我们还可以指定其他配置选项,如下例所示:
We can also specify additional configuration options, as the following example shows:
-
Java
-
Kotlin
WebClient webClient;
@BeforeEach
void setup() {
webClient = MockMvcWebClientBuilder
// demonstrates applying a MockMvcConfigurer (Spring 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();
}
lateinit var webClient: WebClient
@BeforeEach
fun setup() {
webClient = MockMvcWebClientBuilder
// demonstrates applying a MockMvcConfigurer (Spring 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()
}
作为一种替代方法,我们可以通过分别配置 MockMvc
实例并将其提供给 MockMvcWebClientBuilder
来执行完全相同的设置,如下所示:
As an alternative, we can perform the exact same setup by configuring the MockMvc
instance separately and supplying it to the MockMvcWebClientBuilder
, as follows:
-
Java
-
Kotlin
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();
// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed
这种方法较为详细,但是,通过使用 MockMvc
实例构建 WebClient
,我们可以随时充分利用 MockMvc 的强大功能。
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 |