当我使用grails 2.4.4生成控制器和相关的单元测试类时,即使我在populateValidParams()中设置了必要的测试数据后,我也会遇到测试失败。我可以通过将 model.personInstance!= null (对于Person类)更改为 model.person!= null 来修复大多数失败。我很惊讶这是必要的,但至少它是有效的。
其他测试失败发生在保存,更新和删除相关测试上,并因 response.redirectUrl 为空。通过使用调试器逐步执行它,似乎 request.withFormat 闭包正在访问通配符语句而不是 form / multipartForm 块。我认为生成的单元测试中的 request.contentType = FORM_CONTENT_TYPE 应该导致代码命中代码的 form / multipartForm 部分。
这是我正在为只需要firstName和lastName字段的Person域类测试的代码...
域类:
package org.crspta.gohomenotes
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode()
class Person implements Serializable {
User user
Date dateCreated
Date lastUpdated
String firstName
String middleName
String lastName
String nickname
String emailAddress
String cellPhone
String homePhone
String workPhone
static constraints = {
firstName nullable: false
middleName nullable: true
lastName nullable: false
nickname nullable: true
emailAddress nullable: true, email: true
cellPhone nullable: true
homePhone nullable: true
workPhone nullable: true
user nullable: true
}
@Override
public String toString() {
return "${name}"
}
public String getName() {
def name = "$lastName, $firstName"
if (nickname) {
name += " ($nickname)"
}
return name
}
}
PersonControllerSpec:
@TestFor(PersonController)
@Mock(Person)
class PersonControllerSpec extends Specification {
def populateValidParams(params) {
assert params != null
params["firstName"] = 'Firstname'
params["lastName"] = 'Lastname'
}
由于response.redirectUrl为空而失败的单元测试方法。
void "Test the save action correctly persists an instance"() {
when:"The save action is executed with an invalid instance"
request.contentType = FORM_CONTENT_TYPE
request.method = 'POST'
def person = new Person()
person.validate()
controller.save(person)
then:"The create view is rendered again with the correct model"
model.person != null
view == 'create'
when:"The save action is executed with a valid instance"
response.reset()
populateValidParams(params)
person = new Person(params)
controller.save(person)
then:"A redirect is issued to the show action"
response.redirectedUrl == '/person/show/1'
controller.flash.message != null
Person.count() == 1
}
PersonController save()方法:
@Transactional
def save(Person personInstance) {
if (personInstance == null) {
notFound()
return
}
if (personInstance.hasErrors()) {
respond personInstance.errors, view:'create'
return
}
personInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'person.label', default: 'Person'), personInstance.id])
redirect personInstance
}
'*' { respond personInstance, [status: CREATED] }
}
}
特定错误消息:
Condition not satisfied:
response.redirectedUrl == '/person/show/1'
| | |
| null false
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse@17134f55
<Click to see difference>
at org.crspta.gohomenotes.PersonControllerSpec.Test the save action correctly persists an instance(PersonControllerSpec.groovy:56)