我正在尝试创建控制器规范,在这种情况下,对于未授权访问此资源的用户。我需要检测重定向的状态,位置以及来自Devise / Cancan的消息。
经过多次黑客攻击后,我想出了这个。
context 'with unauthorized user' do
describe 'GET #index' do
subject { xhr :get, :index, {} }
it { subject; response.status.should eq 401 } #successfully detects unauthorized
it { should redirect_to new_user_session_path } #Expected response to be a <redirect>, but was <401>
it 'redirects' do
get :index, {}
expect(response).to redirect_to(new_user_session_path) #successfully detects redirect
# how to get the Devise message?
end
end
end
有人可以帮我理解这里发生的事情。
xhr :get, :index
和get :index,
{}
之间有什么区别。subject; response.status.should eq
401
和`response.status.should eq 401&#39; 答案 0 :(得分:2)
Controller specs存根应用程序的许多层。例如,他们实际上并不创建HTTP请求或通过路由层。它们也默认不渲染视图。这使得测试更快一些,但是存根确实在测试敏锐度方面有成本。
get :foo
创建一个伪造HTTP请求的请求对象。 Rails通过查看您的路线并尝试找到与params相匹配的东西来做到这一点。 xhr :foo
大致相同,但会设置请求标头,因此它似乎是XHR请求。
redirect_to 匹配器测试响应是HTTP重定向。这意味着响应代码应该在300-399范围内并包含位置标题。
要测试其他响应代码,您应该执行以下操作:
context 'with unauthorized user' do
describe 'GET #index' do
before { get :index }
subject { response }
it { is_expected.to have_http_status 401 }
it "redirects to login" do
expect(response.headers[:location]).to equal new_user_session_path
end
end
end
答案很简单,就是在上下文中使用render_views
,它会在response.body
中为您提供正文。但是,由于实际上没有遵循重定向,因此这将无法正常工作。
考虑使用功能规范来测试此行为:
RSpec.feature "Foos" do
context "A guest" do
scenario "should not be able to view all Foos" do
visit "/foos"
expect(response).to have_content "You are not allowed to view this page"
end
end
end