我在grails中有这个单元测试方法
void "test if login action returns the correct model"() {
when:"login is called without any parameters(null user) "
params.max = 0
def model = controller.login(null)
then:"it must return an empty user model"
null == model.user.userName
null == model.user.password
when:"login is called with fields with errors"
params.userName = "ama"
params.password = "aam"
def model1 = controller.login()
then:"it must return a model which has errors"
// !model1.user.validate() // i commented this out because i want to get rejected values not errors that come from the constraints block
println model1.user.userName // prints "ama"
model1.user.hasErrors()
null != model1.user.errors.getFieldError('password')
null != model1.user.errors.getFieldError('userName')
when:"when user is not found"
params.userName = "amanu"
params.password = "aam"
def model2 = controller.login()
then:"it must return a model with userName field with error"
"amanu"==model2.user.userName
// model2.user.hasErrors()
"user.login.username.not.found"==model2.user.errors.getFieldError('userName').code
}
这是登录操作
def login (User user){
if(user){
boolean error = false
if(!user.userName){
error = true
user.errors.rejectValue("userName", "user.login.username.empty","User Name can not be empty!")
}
if(!user.password){
error = true
user.errors.rejectValue("password", "user.login.password.empty","Password can not be empty!")
}
if(!error){
User u = User.findByUserName(user.userName);
if(!u){
//User Name does not exist
user.errors.rejectValue("userName", "user.login.username.not.found","User Name was not found!")
}else if(u?.password != user.password.encodeAsPassword()){
//password does not match
user.errors.rejectValue("password", "user.login.password.invalid","User Name or Password was Incorrect!")
}else{
//both match here
session.user = user
if(params.after){
if(!params.after.controller){
redirect( uri:"/");
return;
}
def action = params.after.action?:'index'
redirect controller:params.after.controller, action:action
return
}
redirect uri:'/'
return
//redirect and return
}
}
//return the user anyways
return [user: user]
}else{
return [user:new User(params)]
}
}
这是问题所在!上面的控制器成功地将正确的模型发送到视图,在视图中我可以成功检查hasError方法,它可以在不调用validate方法的情况下工作!它向我展示了我拒绝的价值观!
但是当我在测试中调用hasErrors()
时,它返回false!我做错了什么?
答案 0 :(得分:0)
验证由框架执行,作为请求周期的一部分。在单元测试中,您需要明确地调用它。
在我看来,你在控制器的单元测试中对你的模型进行了部分测试。也许你可以将一些测试移到模型单元测试中?另一种方法是编写集成测试,执行整个请求周期。要看到这一切都在一起。
答案 1 :(得分:0)
回答我自己的问题!我终于得到了我做错的事。我没有将任何参数传递给controller.login()
,这意味着它被调用null并且只会发送由params创建的空模型(这就是为什么我得到了userName权限)!
因此,当使用命令对象测试操作时(如果命令对象是域),只有在请求为POST时才会创建它,否则将为null。
因此,测试时记得传递一个参数!如果命令对象不是域对象,则将调用构造函数并在病毒之后调用bindData!