领先一步
VMware 提供培训和认证,助您加速进步。
了解更多在我的第三篇文章中,我讨论了如何使用WebDriver 结合 Page Object Pattern 来简化我们的测试设计。在这篇文章中,我将讨论如何使用 Geb 来让我们的 MockMvc 测试更具 Groovy 风格。
Geb 基于 WebDriver,因此它提供了许多与 WebDriver 相同的优势。然而,Geb 通过处理一些样板代码,使事情变得更加简单。当然,我们希望使用 MockMvc,这样就不需要将我们的代码部署到服务器上。理解使用 Geb 的好处最简单的方法就是看一个例子。
注意:Geb 的另一个很棒的功能是它出色的文档。
在使用该项目之前,您必须确保更新您的依赖项。可以在网站文档中找到 Maven 和 Gradle 的说明。
现在我们有了正确的依赖项,我们可以在单元测试中使用 Geb。关于使用 Geb 和 Spring MVC Test 的完整代码示例可以在GebCreateMessagesSpec 中找到。
为了使用 HtmlUnit 和 Spring MVC Test,我们必须首先创建一个 MockMvc 实例。关于如何创建 MockMvc 实例的文档有很多,但我们将在本节中快速回顾如何创建 MockMvc 实例。
第一步是创建一个新的 GebReportingSpec 类,并按如下方式进行注解
@ContextConfiguration(classes=[WebMvcConfig,MockDataConfig])
@WebAppConfiguration
class GebCreateMessagesSpec extends GebReportingSpec {
@Autowired
WebApplicationContext context;
WebDriver driver;
...
}
@Autowired 注解会被尊重的原因。@ContextConfiguration告诉Spring加载哪个配置。您会注意到我们正在加载一个模拟的数据库层实例以提高测试性能。如果我们愿意,也可以选择在真实数据库上运行测试。然而,这存在我们之前提到过的缺点。@WebAppConfiguration 指示应创建 WebApplicationContext 而不是 ApplicationContext。接下来,我们需要从context创建我们的MockMvc实例。下面提供了一个如何做到这一点的示例
def setup() {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build()
...
}
当然,这只是创建MockMvc实例的一种方式。我们也可以选择添加Servlet Filter,使用Standalone setup等。重要的是我们需要一个MockMvc的实例。有关创建MockMvc实例的更多信息,请参阅Spring MVC Test文档。
现在我们已经创建了 MockMvc 实例,我们需要创建一个 MockMvcHtmlUnitDriver,它确保我们使用的是在上一步中创建的 MockMvc 实例。然后,我们使用 Geb 的显式生命周期并将驱动程序设置在 Geb 的Browser 实例上。
WebDriver driver;
def setup() {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build()
driver = new MockMvcHtmlUnitDriver(mockMvc, true)
browser.driver = driver
}
def destroy() {
if(driver != null) {
driver.close();
}
}
现在我们可以像平常一样使用 Geb,而无需部署我们的应用程序。例如,我们可以通过以下方式请求创建消息的视图
to CreateMessagePage
然后,我们可以填写表单并提交以创建消息。
form.summary = expectedSummary
form.text = expectedMessage
submit.click(ViewMessagePage)
任何未识别的方法调用或属性访问/引用(如果找不到)将被转发到当前页面对象。这消除了我们直接使用 WebDriver 时需要的许多样板代码。
此外,这改进了我们HtmlUnit 测试的设计。最明显的变化是我们现在正在使用页面对象模式。正如我们在为什么是 WebDriver?中提到的,我们可以使用页面对象模式与 HtmlUnit 结合,但现在它要容易得多。
让我们看一下我们的 CreateMessagePage。
class CreateMessagePage extends Page {
static url = 'messages/form'
static at = { assert title == 'Messages : Create'; true }
static content = {
submit { $('input[type=submit]') }
form { $('form') }
errors(required:false) { $('label.error, .alert-error')?.text() }
}
}
您注意到的第一件事是我们的 CreateMessagePage 扩展了 Page。我们不会详细介绍 Page 的细节,但总而言之,它包含了所有页面所需的基本功能。
接下来您会注意到我们定义了该页面可以找到的 URL。这允许我们通过以下方式导航到页面
to CreateMessagePage
我们还有一个闭包,用于确定我们是否在指定的页面上。如果我们在正确的页面上,它应该返回 true。这就是为什么我们可以使用以下方式断言我们在正确的页面上
注意:我们在闭包中使用断言,这样如果我们在错误的页面上,我们就可以确定哪里出了问题。
at CreateMessagePage
最后,我们创建一个内容闭包,它指定页面内所有感兴趣的区域。我们可以使用类似 jQuery 的导航器 API来选择我们感兴趣的内容。
最后,我们可以验证是否成功创建了新消息
at ViewMessagePage
success == 'Successfully created a new message'
id
date
summary == expectedSummary
message == expectedMessage
欢迎反馈!
如果您对这个博客系列或 Spring Test MVC HtmlUnit 有任何反馈,我鼓励您通过下面的评论、github issues 或在 Twitter 上@rob_winch 与我联系。当然,最好的反馈是以贡献的形式出现的。