领先一步
VMware 提供培训和认证,助您加速进步。
了解更多在我 上一篇文章中,我介绍了 Spring Test MVC HtmlUnit 并解释了该项目的动机。在这篇文章中,我将介绍如何使用 Spring MVC Test 配合 HtmlUnit。
在使用该项目之前,您必须确保更新您的依赖项。可以在网站文档中找到 Maven 和 Gradle 的说明。
既然我们已经有了正确的依赖,我们就可以在单元测试中使用HtmlUnit了。我们的示例假定您已经将JUnit添加为依赖项。如果您还没有添加,请相应地更新您的类路径。使用HtmlUnit和Spring MVC Test的完整代码示例可以在 MockMvcHtmlUnitCreateMessageTest 中找到。
为了使用HtmlUnit和Spring MVC Test,我们必须首先创建一个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 Filter,使用Standalone setup等。重要的是我们需要一个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:///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 issues与我联系,或在twitter上@rob_winch。当然,最好的反馈是贡献。