我正在尝试测试用户登录的典型控制器流程。与大多数登录系统一样,存在扩展关系,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为null,即使它应该有一个值,redirectedUrl为null,内容正文为空,视图也是如此。
如果我删除@TestFor注释,即使是最轻微的也无法正常工作。它没有告诉我'params'不存在。
在另一个测试中,我有两种方法。第一个方法运行,找到Person.findAllByEmail(),然后第二个方法运行,找不到Person.findAllByEmail并崩溃,类似的错误 - 方法丢失。
在另一个奇怪的更新中 - 看起来响应对象正在向应用程序baseUrl发回重定向,而不是向用户控制器发送。
答案 0 :(得分: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
}
}
详细信息位于user guide。
答案 1 :(得分:0)
TestFor
注释仅用于单元测试,因为这会模拟结构。在integration tests中您可以访问完整的Grails环境,因此不需要这些模拟。所以只需删除注释即可。
class UserControllerTests extends GroovyTestCase {
...
}