如何使用Rspec和Capybara测试重定向
我不知道我做错了什么,但每次我尝试测试重定向时,都会收到此错误:“@request必须是ActionDispatch :: Request”
context "as non-signed in user" do it "should redirect to the login page" do expect { visit admin_account_url(account, host: get_host(account)) }.to redirect_to(signin_path) end end 1) AdminAccountPages Admin::Accounts#show as non-signed in user should redirect to the login page Failure/Error: expect { visit admin_account_url(account, host: get_host(account)) }.to redirect_to(signin_path) ArgumentError: @request must be an ActionDispatch::Request # ./spec/requests/admin_account_pages_spec.rb:16:in `block (4 levels) in '
我正在使用带有Capybara(1.1.2)和Rails 3.2的RSpec-rails(2.9.0)。 如果有人能解释为什么会这样,我将不胜感激; 为什么我不能以这种方式使用期望?
Capybara不是特定于rails的解决方案,所以它对rails的渲染逻辑一无所知。
Capybara专门用于集成测试,它实质上是从最终用户与浏览器交互的角度运行测试。 在这些测试中,您不应该断言模板,因为最终用户无法深入了解您的应用程序。 你应该测试的是一个动作让你走上正确的道路。
current_path.should == new_user_path page.should have_selector('div#erro_div')
你可以这样做:
expect(current_path).to eql(new_app_user_registration_path)
错误消息@request must be an ActionDispatch::Request
告诉你rspec-rails matcher redirect_to
(它委托给Rails assert_redirected_to
)期望它在Railsfunction测试中使用(应该在ActionController::TestCase
混合使用)。 您发布的代码看起来像rspec-rails请求规范。 所以redirect_to
不可用。
rspec-rails请求规范不支持检查重定向,但Rails集成测试支持。
是否应该明确检查重定向是如何进行的(它是301响应而不是307响应而不是某些javascript)完全取决于您。
Rspec 3:
测试当前路径的最简单方法是:
expect(page).to have_current_path('/login?status=invalid_token')
have_current_path
比这种方法有优势:
expect(current_path).to eq('/login')
因为你可以包含查询参数。
这是我发现的hackish解决方案
# spec/features/user_confirmation_feature.rb feature 'User confirmation' do scenario 'provide confirmation and redirect' do visit "/users/123/confirm" expect(page).to have_content('Please enter the confirmation code') find("input[id$='confirmation_code']").set '1234' do_not_follow_redirect do click_button('Verify') expect(page.driver.status_code).to eq(302) expect(page.driver.browser.last_response['Location']).to match(/\/en\//[^\/]+\/edit$/) end end protected # Capybara won't follow redirects def do_not_follow_redirect &block begin options = page.driver.instance_variable_get(:@options) prev_value = options[:follow_redirects] options[:follow_redirects] = false yield ensure options[:follow_redirects] = prev_value end end end