Grails 1.1 引入 GrailsUnitTestCase 及其子類,透過內建 Mock 機制,讓單元測試在隔離環境中也能享有 GORM 動態方法、驗證邏輯、日誌注入等完整功能,大幅提升測試速度並減少對資料庫的依賴。本文系統講解核心 Mock 方法、Controller 測試技巧與 REST 服務驗證。
GroovyTestCase → 基礎斷言GrailsUnitTestCase → 領域類、Service 測試ControllerUnitTestCase → Controller 測試(繼承前者)| 方法 | 用途 | 適用場景 |
|---|---|---|
mockForConstraintsTests() | 注入驗證方法、errors 集合 | 測試 constraints 定義 |
mockDomain() | 模擬 GORM 持久化方法 | 測試 save、list、動態查詢 |
mockLogging() | 注入 log 實例 | Service、Controller 使用 log |
void testBlank() {
mockForConstraintsTests(User)
def user = new User(name: "", login: "admin", password: "wordpass")
assertFalse user.validate()
assertEquals 1, user.errors.errorCount
assertEquals "blank", user.errors["name"]
}
void testUniqueLogin() {
def existing = [new User(login: "jdoe"), new User(login: "suziq")]
mockForConstraintsTests(User, existing)
def duplicate = new User(login: "jdoe")
assertFalse duplicate.validate()
assertEquals "unique", duplicate.errors["login"]
}
void testMockDomain() {
def users = [new User(name: "John", role: "user"),
new User(name: "Jane", role: "admin")]
mockDomain(User, users)
assertEquals 1, User.findAllByRole("admin").size()
def newUser = new User(login: "new", role: "user")
newUser.save()
assertEquals 3, User.findAllByRole("user").size() // id 自動分配
}
void testIndex() {
controller.session.user = new User(role: "user")
controller.index()
assertEquals "home", controller.redirectArgs.controller
assertTrue controller.flash.message.startsWith("Sorry")
controller.session.user = new User(role: "admin")
controller.index()
assertEquals controller.list, controller.redirectArgs.action
}
void testShow() {
mockDomain(User, [new User(id: 1, name: "Suzi Q")])
controller.params.id = 2
def model = controller.show()
assertEquals "Suzi Q", model.userInstance.name
}
void testListXml() {
mockDomain(User, [new User(login: "suziq", role: "admin")])
controller.listXml()
def xml = controller.response.contentAsString
def root = new XmlParser().parseText(xml)
assertEquals "suziq", root.user.login.text()
}
grails test-app -unit:僅跑單元測試,秒級反饋grails test-app -unit User:針對單一類測試Mock 無法支援:Criteria 查詢、HQL、QBE。涉及此類邏輯請改寫集成測試。