为什么我要再次验证grails

时间:2014-11-11 07:54:50

标签: unit-testing grails

我在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!我做错了什么?

2 个答案:

答案 0 :(得分:0)

验证由框架执行,作为请求周期的一部分。在单元测试中,您需要明确地调用它。

在我看来,你在控制器的单元测试中对你的模型进行了部分测试。也许你可以将一些测试移到模型单元测试中?另一种方法是编写集成测试,执行整个请求周期。要看到这一切都在一起。

答案 1 :(得分:0)

回答我自己的问题!我终于得到了我做错的事。我没有将任何参数传递给controller.login(),这意味着它被调用null并且只会发送由params创建的空模型(这就是为什么我得到了userName权限)!

因此,当使用命令对象测试操作时(如果命令对象是域),只有在请求为POST时才会创建它,否则将为null。

因此,测试时记得传递一个参数!如果命令对象不是域对象,则将调用构造函数并在病毒之后调用bindData!