领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多在我之前的文章中,我介绍了 Spring Test MVC HtmlUnit 并解释了该项目背后的动机。在这篇文章中,我将描述如何使用 Spring MVC Test 与HtmlUnit一起使用。
在使用该项目之前,您必须确保更新您的依赖项。有关Maven和Gradle的说明可以在站点文档中找到。
现在我们有了正确的依赖项,我们可以在单元测试中使用 HtmlUnit。我们的示例假设您已经将 JUnit 作为依赖项。如果您尚未添加它,请相应地更新您的类路径。有关使用 HtmlUnit 和 Spring MVC Test 的完整代码示例,请参见MockMvcHtmlUnitCreateMessageTest。
为了使用 HtmlUnit 和 Spring MVC Test,我们必须首先创建一个MockMvc
实例。关于如何创建MockMvc
实例有很多文档,但我们将在本节中快速回顾一下如何创建MockMvc
实例。
第一步是创建一个新的 JUnit 类,并使用如下所示的注解进行标记
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebMvcConfig.class, MockDataConfig.class})
@WebAppConfiguration
public class MockMvcHtmlUnitCreateMessageTest {
@Autowired
private WebApplicationContext context;
...
}
@RunWith(SpringJUnit4ClassRunner.class)
允许 Spring 对我们的MockMvcHtmlUnitCreateMessageTest
进行依赖注入。这就是为什么我们的@Autowired
注解会被认可的原因。@ContextConfiguration
告诉 Spring 加载哪个配置。您会注意到我们正在加载数据层的一个模拟实例以提高测试的性能。如果需要,我们可以选择针对真实数据库运行测试。但是,这具有我们之前提到的缺点。@WebAppConfiguration
指示SpringJUnit4ClassRunner
它应该创建一个WebApplicationContext
而不是ApplicationContext
。接下来,我们需要从context
中创建我们的MockMvc
实例。下面提供了一个如何执行此操作的示例
@Before
public void setup() {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
...
}
当然,这只是创建MockMvc
实例的一种方法。我们可以选择添加一个 Servlet 过滤器,使用独立设置等。重要的是我们需要一个MockMvc
的实例。有关创建MockMvc
实例的更多信息,请参阅Spring MVC Test 文档。
现在我们已经创建了MockMvc
实例,我们需要创建一个 HtmlUnit WebClient
。我们使用MockMvcWebConnection
来确保 HtmlUnit 使用我们在上一步中创建的MockMvc
实例。
private WebClient webClient;
@Before
public void setup() {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
webClient = new WebClient();
webClient.setWebConnection(new MockMvcWebConnection(mockMvc));
}
现在我们可以像往常一样使用 HtmlUnit,但无需部署我们的应用程序。例如,我们可以使用以下方法请求创建消息的视图
HtmlPage createMsgFormPage =
webClient.getPage("https://127.0.0.1/mail/messages/form");
注意主机后面的第一个路径段/mail
被视为上下文根。目前不支持/
的上下文根。请参阅spring-test-mvc-htmlunit/issues/20以获取有关此问题的更新。
然后我们可以填写表单并提交它以创建消息。
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();
最后,我们可以验证新消息是否已成功创建
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!");
这以多种方式改进了我们的MockMvc 测试。首先,我们不再需要显式验证我们的表单,然后创建一个类似于表单的请求。相反,我们请求表单,填写它并提交它。这大大减少了开销。
另一个重要因素是HtmlUnit 使用 Mozilla Rhino 引擎来评估页面上的 JavaScript。这意味着,我们也可以验证我们的 JavaScript 方法!
有关完整示例,请参阅MockMvcHtmlUnitCreateMessageTest。有关使用 HtmlUnit 的更多信息,请参阅HtmlUnit 文档。
HtmlUnit
极大地提高了我们的生产力和测试范围。但是,我们仍然可以通过添加更高层次的抽象来改进我们的测试。在我们的下一篇文章中,我们将看到如何将WebDriver
与MockMvc
一起使用以使我们的测试代码更易于重用。
请提供反馈!
如果您对本博客系列或 Spring Test MVC HtmlUnit 有任何反馈,我鼓励您通过github 问题联系我们或在 Twitter 上联系我@rob_winch。当然,最好的反馈是以贡献的形式出现的。