我有一个控制器在某些条件下在某些点重定向。当我将参数传递给我的控制器规范中的规范帮助器方法(使用最新的RSpec)来触发这些条件时,我得到了一个
ActionView::MissingTemplate
错误。仔细检查我应该重定向时,我会做如下行:
redirect_to root_path && return
然后在我的测试套件中抛出异常。我在应该调用的控制器的索引函数中设置了一个断点(我正在重定向到的路由指向),并且在我的测试套件中永远不会调用它。当我在我的开发环境和生产环境中运行它时,这段代码似乎有效,但是对于这个测试,它只是不会让步。有什么想法吗?
我的测试看起来像这样:
describe TestController do
it 'redirects properly with failure' do
get :create, provider: 'test', error: 'access_denied'
expect(response.body).to match 'test'
end
end
编辑:
更新!
似乎将我的重定向更改为
redirect_to root_path and return
适用于RSpec。
我不知道为什么&&
运算符的优先级违反了规范。有没有人解释这里发生了什么?
答案 0 :(得分:4)
请务必使用
and return
代替&& return
,因为由于Ruby语言中的运算符优先级,&& return
将无效。
如果您更喜欢使用&&
,请将参数括在render
的括号中:
redirect_to(root_path) && return
答案 1 :(得分:4)
差异&&
比and
高precedence。高优先级导致ruby解析为
redirect_to(root_path && return)
方法当然必须在调用方法本身之前评估它们的参数,因此在这种情况下永远不会调用redirect_to
,因为ruby首先命中return
。
另一方面,and
的优先级较低意味着它被解析为
(redirect_to root_path) and return
您想要的是 - 首先进行重定向,然后返回。
答案 2 :(得分:1)
测试控制器时模板必须存在,因为默认情况下视图是存根的。请参阅RSpec Documentation
因此,请确保为控制器操作提供模板。
答案 3 :(得分:1)
默认控制器规范不遵循重定向。因此,永远不会调用您的索引操作。相反,您应该检查它是否从服务器收到了正确的重定向订单:
describe TestController do
it 'redirects properly with failure' do
get :create,
provider: 'test',
error: 'access_denied'
expect(response).to redirect_to root_path
end
end
这称为测试隔离:您只测试创建操作重定向到特定点。索引操作的真正工作原理应该在控制器的索引规范中进行测试,而不是在创建规范中进行测试。
答案 4 :(得分:0)
解释&&
和and
的不同运算符优先级的答案是正确的。但是,检查render
或redirect_to
的返回值的整个想法是误导性的,Rails指南不应该推荐它。
render
和redirect_to
会因其副作用(他们修改响应)而被调用,而不是因为它们的返回值。如果他们有错误,他们会引发异常,而不是返回虚假值。因此,使用&&
或and
会产生误导。相反,做
redirect_to root_path
return
向读者清楚地说明代码是如何工作的,并避免与操作员一起讨论这些问题。