MockMvc 與 Geb

在前一節中,我們看到了如何將 MockMvc 與 WebDriver 搭配使用。在本節中,我們將使用 Geb 讓我們的測試更 Groovy 化。

為何選擇 Geb 和 MockMvc?

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

MockMvc 與 Geb 設定

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

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-ish Navigator API 來選擇我們感興趣的內容。

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

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

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