MockMvc 和 Geb

在上一節中,我們瞭解瞭如何將 MockMvc 與 WebDriver 結合使用。在本節中,我們使用 Geb 使測試更 Groovy 化。

為何選擇 Geb 和 MockMvc?

Geb 以 WebDriver 為基礎,因此它提供了與 WebDriver 相同的許多優勢。然而,Geb 透過為我們處理一些樣板程式碼,使事情變得更加簡單。

MockMvc 和 Geb 設定

我們可以輕鬆地初始化一個使用 MockMvc 的 Selenium WebDriver 的 Geb Browser,如下所示:

def setup() {
	browser.driver = MockMvcHtmlUnitDriverBuilder
		.webAppContextSetup(context)
		.build()
}
這是使用 MockMvcHtmlUnitDriverBuilder 的一個簡單示例。有關更高階的用法,請參閱高階 MockMvcHtmlUnitDriverBuilder

這確保了任何引用 localhost 作為伺服器的 URL 都被定向到我們的 MockMvc 例項,而無需真實的 HTTP 連線。任何其他 URL 則像往常一樣使用網路連線請求。這使我們可以輕鬆測試 CDN 的使用。

MockMvc 和 Geb 用法

現在我們可以像往常一樣使用 Geb,而無需將應用程式部署到 Servlet 容器。例如,我們可以使用以下程式碼請求建立訊息的檢視:

to CreateMessagePage

然後我們可以填寫表單並提交它來建立訊息,如下所示:

when:
form.summary = expectedSummary
form.text = expectedMessage
submit.click(ViewMessagePage)

任何未識別的方法呼叫、屬性訪問或未找到的引用都會轉發到當前頁面物件。這消除了我們直接使用 WebDriver 時所需的許多樣板程式碼。

與直接使用 WebDriver 一樣,這透過使用頁面物件模式改進了我們的 HtmlUnit 測試設計。如前所述,我們可以在 HtmlUnit 和 WebDriver 中使用頁面物件模式,但使用 Geb 更加容易。請考慮我們新的基於 Groovy 的 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

我們還有一個 at 閉包,用於判斷我們是否在指定的頁面。如果我們在正確的頁面,它應該返回 true。這就是為什麼我們可以斷言我們在正確的頁面,如下所示:

then:
at CreateMessagePage
errors.contains('This field is required.')
我們在閉包中使用了一個斷言,這樣如果我們在錯誤的頁面,就可以確定問題出在哪裡。

接下來,我們建立一個 content 閉包,指定頁面中所有感興趣的區域。我們可以使用一個類似 jQuery 的 Navigator API 來選擇我們感興趣的內容。

最後,我們可以驗證是否成功建立了一條新訊息,如下所示:

then:
at ViewMessagePage
success == 'Successfully created a new message'
id
date
summary == expectedSummary
message == expectedMessage

有關如何充分利用 Geb 的更多詳細資訊,請參閱《Geb 之書》使用者手冊。