MockMvc and Geb
Why Geb and MockMvc?
Geb 受 WebDriver 的支持,因此它提供了许多我们从same benefits 获得的same benefits 。然而,Geb 通过代我们处理一些样板代码,让事情变得更加轻松。
Geb is backed by WebDriver, so it offers many of the same benefits that we get from WebDriver. However, Geb makes things even easier by taking care of some of the boilerplate code for us.
MockMvc and Geb Setup
我们可以用一个 Selenium WebDriver 和 MockMvc 初始化一个 Geb Browser
,如下所示:
We can easily initialize a Geb Browser
with a Selenium WebDriver that uses MockMvc, as
follows:
def setup() {
browser.driver = MockMvcHtmlUnitDriverBuilder
.webAppContextSetup(context)
.build()
}
这是一个使用 |
This is a simple example of using |
这确保了将任何引用 localhost
作为服务器的 URL 定向到我们的 MockMvc
实例,而不需要真正的 HTTP 连接。任何其他 URL 都按正常方式使用网络连接请求。这让我们很容易测试 CDN 的使用。
This ensures that any URL referencing 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 Geb Usage
现在,我们可以像往常一样使用 Geb,但不需要将我们的应用程序部署到 Servlet 容器中。例如,我们可以请求视图来用以下方法创建一个消息:
Now we can use Geb 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:
to CreateMessagePage
然后,我们可以填写表单并提交它来创建消息,如下所示:
We can then fill out the form and submit it to create a message, as follows:
when:
form.summary = expectedSummary
form.text = expectedMessage
submit.click(ViewMessagePage)
任何未识别的调用方法或属性访问或找不到的引用都会转发到当前页面对象。这消除了在直接使用 WebDriver 时所需的许多样板代码。
Any unrecognized method calls or property accesses or references that are not found are forwarded to the current page object. This removes a lot of the boilerplate code we needed when using WebDriver directly.
与直接使用 WebDriver 一样,这通过使用页面对象模式改进了我们HtmlUnit test 的设计。如前所述,我们可以在 HtmlUnit 和 WebDriver 中使用页面对象模式,但使用 Geb 更加容易。考虑我们的基于 Groovy 的新`CreateMessagePage` 实现:
As with direct WebDriver usage, this improves on the design of our
HtmlUnit test by using the Page Object
Pattern. As mentioned previously, we can use the Page Object Pattern with HtmlUnit and
WebDriver, but it is even easier with Geb. Consider our new Groovy-based
CreateMessagePage
implementation:
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。这允许我们导航到页面,如下所示:
Our CreateMessagePage
extends Page
. We do not go over the details of Page
, but, in
summary, it contains common functionality for all of our pages. We define a URL in which
this page can be found. This lets us navigate to the page, as follows:
to CreateMessagePage
我们还有一些 at
闭包,用于判断我们是否处于指定的页面中。如果我们在正确的页面上,则它应返回 true
。这就是我们可以断言我们处于正确页面中的原因,如下所示:
We also have an at
closure that determines if we are at the specified page. It should
return true
if we are on the correct page. This is why we can assert that we are on the
correct page, as follows:
then:
at CreateMessagePage
errors.contains('This field is required.')
我们使用闭包中的断言,以便如果我们不在正确的页面,我们可以确定哪里出错了。 |
We use an assertion in the closure so that we can determine where things went wrong if we were at the wrong page. |
接下来,我们创建一个 content
闭包,指定页面中的所有感兴趣的区域。我们可以使用 jQuery-ish Navigator
API 选择我们感兴趣的内容。
Next, we create a content
closure that specifies all the areas of interest within the
page. We can use a
jQuery-ish Navigator
API to select the content in which we are interested.
最后,我们可以验证现在已成功创建消息,如下所示:
Finally, we can verify that a new message was created successfully, as follows:
then:
at ViewMessagePage
success == 'Successfully created a new message'
id
date
summary == expectedSummary
message == expectedMessage
有关如何充分利用 Geb 的更多详细信息,请参见 The Book of Geb 用户手册。
For further details on how to get the most out of Geb, see The Book of Geb user’s manual.