For the latest stable version, please use Spring Framework 6.2.0! |
MockMvc and Geb
In the previous section, we saw how to use MockMvc with WebDriver. In this section, we use Geb to make our tests even Groovy-er.
Why Geb and MockMvc?
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
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 MockMvcHtmlUnitDriverBuilder . For more advanced
usage, see Advanced MockMvcHtmlUnitDriverBuilder .
|
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
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)
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.
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() }
}
}
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
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. |
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
For further details on how to get the most out of Geb, see The Book of Geb user’s manual.