2

我正在尝试测试用户登录的典型控制器流程。与大多数登录系统一样,存在扩展关系,而 Grails 文档完全没用。它没有一个与典型用法实际相关的示例,并且是一个功能完整的示例。

我的测试如下所示:

@TestFor(UserController)
class UserControllerTests extends GroovyTestCase {
    void testLogin() {
        params.login = [email: "test1@example.com", password: "123"]
        controller.login()
        assert "/user/main" == response.redirectUrl
    }
}

控制器会:

def login() {
    if (!params.login) {
        return
    }
    println("Email " + params.login.email)
    Person p = Person.findByEmail(params?.login?.email)
    ...
}

失败了:

groovy.lang.MissingMethodException:没有方法签名:immigration.Person.methodMissing() 适用于参数类型:() 值:[]

println 中显示了正确的数据,但是调用该方法失败。

测试套件不能整体使用模拟,因为有被调用的数据库触发器,其结果需要测试。

奇怪的是,如果我在测试中直接调用该方法,它可以工作,但在控制器中调用它却不行。

更新:我直接从 grails 命令重新生成了测试,并添加了 @Test 注释:

    @TestFor(UserController)
    class UserControllerTests extends GroovyTestCase {
        @Test
        void testLogin() {
            params.login = [email: "test1@example.com", password: "123"]
            Person.findByEmail(params.login.email)
            controller.login()
        }
    }

如果我使用 grail test-app -integration UserController 运行它,这将有效

尽管结果未正确填充 - 响应为空,flash.message 为空,即使它应该有一个值,redirectedUrl 为空,内容正文为空,视图也是如此。

如果我删除 @TestFor 注释,它甚至不会工作。它没有告诉我“参数”不存在。

在另一个测试中,我有两种方法。第一个方法运行,找到 Person.findAllByEmail(),然后第二个方法运行,找不到 Person.findAllByEmail 并崩溃并出现类似的错误 - 方法丢失。

在另一个奇怪的更新中 - 看起来响应对象正在发送重定向,但发送回应用程序 baseUrl,而不是发送到用户控制器。

4

2 回答 2

6

集成测试不应该使用@TestFor. 您需要在测试中创建控制器实例,并在其中设置参数:

class UserControllerTests extends GroovyTestCase {
  void testLogin() {
    def controller = new UserController()
    controller.params.login = [email:'test1@example.com', password:'123']
    controller.login()
    assert "/user/main" == controller.response.redirectedUrl
  }
}

详细信息在用户指南中。

于 2012-12-08T10:41:52.383 回答
0

TestFor注释仅用于单元测试,因为它模拟了结构。在集成测试中,您可以访问完整的 Grails 环境,因此不需要这个模拟。所以只需删除注释就可以了。

class UserControllerTests extends GroovyTestCase {
...
}
于 2012-12-06T19:24:11.477 回答