我创建了一个RSpec规范来测试POST #create操作是否正常工作:
let vc = ViewController() //change this to your class name
self.presentViewController(vc, animated: true, completion: nil)
以上代码正常运行。当我创建另一个测试以仅允许角色为“admin”的用户时,会出现此问题。我是否需要创建新用户,登录,然后运行上述测试?我是否需要为将来根据用户角色进行限制的所有测试执行此操作?
还有其他方法可以进行此类测试吗? 1)只测试create方法是否有效,2)只允许具有“admin”角色的用户访问GET #new和POST #create方法?
答案 0 :(得分:1)
当您的功能完全开发后,您将要进行以下测试:
这种完整,快乐路径测试的想法是测试中最基本的模式之一,但我不知道它有一个名称,除了被术语“快乐”暗示之外路径"
看起来你正在做TDD。大!要从现在的位置到上面的测试列表,下一个要编写的测试是阻止未登录用户创建职业的测试。要使两个测试同时通过,您需要更改第一个测试以登录管理员。如果您需要更多成功创建职业的测试(项目符号4),是的,您还需要在这些项目中登录管理员。
附注:
除非您已经拥有它,否则我不会将您的快乐路径规范写为控制器规范,而是作为功能规范(验收测试)编写,以便您指定UI的重要部分和集成 - 测试整个堆栈。您的失败身份验证规范可能可用作控制器规范,但您可能决定在用户至少对其中一个方案没有权限时接受测试用户界面。
我真的不喜欢expect {}.to change
语法。它会阻止您对发布结果做出任何其他期望。在您的示例中,我希望HTTP响应状态为200(response.should be_success
)。正如我所说,我的第一个规格是功能规格,而不是控制器规格。
答案 1 :(得分:0)
所以,这是一个有趣的问题。是的,您绝对应该(IMO)测试身份验证与目标方法/操作分开。这些中的每一个都构成一个功能单元,应该进行测试。
在我目前的项目中,我赞成PORO(我经常把它们放在一个名为“管理员”的目录中,虽然我知道很多人都喜欢称他们为“服务”#);对于各种各样的事情,因为它让我隔离功能并独立测试它。所以,我最终会得到类似的东西:
# controllers/foo_controller.rb
class FooController < ApplicationController
before_action :authenticate
def create
@results = FooManager.create(params)
redirect_to (@results[:success] ? my_happy_path : my_sad_path)
end
def authenticate
redirect_to unauthorized_path unless AuthenticationManager.authenticate(params, request)
end
end
# managers/foo_manager.rb
class FooManager
class << self
def create(params)
# do a bunch of great stuff and return a hash (perhaps a
# HashWithIndifferentAccess, if you like) which will
# allow for evaluation of @results[:success] back in the
# controller.
end
end
end
# managers/authentication_manager.rb
class AuthenticationManager
class << self
def authenticate(params, request)
# do a bunch of great stuff and return a boolean
end
end
end
通过这样的方法,我可以非常轻松地独立测试FooManager.create
和AuthenticationManager.authenticate
(以及FooController.create
和FooController.authenticate
路由)。万岁!
现在,无论您的身份验证框架或控制器方法在单元级别上是否正常运行,正如Dave指出的那样,这是一个单独的问题,而不是整个系统是否按预期运行。我和他一起进行高级集成测试,这样你就可以清楚地知道做了什么&#39;看起来像你知道什么时候发送它!&#39;