2012-06-08 2 views
17

Я не знаю, что я делаю неправильно, но каждый раз, когда я пытаюсь проверить перенаправление, я получаю эту ошибку: «@request должен быть ActionDispatch :: Запрос»Как проверить перенаправление с помощью Rspec и Capybara

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 <top (required)>' 

Я использую RSpec-рельсы (2.9.0) с Капибарой (1.1.2) и Rails 3.2. Я был бы признателен, если бы кто-то мог объяснить, почему это происходит; почему я не могу использовать ожидание таким образом?

+0

Возможно, мне что-то не хватает, но что случилось с 'assert_redirected_to'? –

+0

@JosephWeissman, я получаю ту же ошибку! – Mohamad

ответ

30

Capybara не является рельсовым решением, так что он ничего не знает о логике рендеринга rails.

Capybara предназначен специально для тестирования интеграции, который, по существу, запускает тесты с точки зрения взаимодействия конечного пользователя с браузером. В этих тестах вы не должны утверждать шаблоны, потому что конечный пользователь не может видеть это глубоко в вашем приложении. То, что вы должны тестировать, заключается в том, что действие наводит вас на правильный путь.

current_path.should == new_user_path 
page.should have_selector('div#erro_div') 
+1

С более новыми версиями Capybara это больше не работает. У меня есть 2.10.1, и есть новый метод 'has_current_path', который можно использовать:' ожидать (страница) .to have_current_path (new_user_path) ' – bjnord

11

Сообщение об ошибке @request must be an ActionDispatch::Request говорит, что RSpec рельсы согласовани redirect_to (это делегатов Рельсы assert_redirected_to) ожидает, что он будет использоваться в Rails функциональные тесты (следует смешивать в ActionController::TestCase). Вывешенный вами код выглядит как спецификация запроса rspec-rails. Таким образом, redirect_to недоступен.

Проверка перенаправления не поддерживается в спецификациях запросов rspec-rails, но поддерживается в тестах интеграции Rails.

Должен ли я явно проверить, как было сделано перенаправление (что это был ответ 301, а не ответ 307, а не какой-то javascript) полностью зависит от вас.

+1

Спасибо за объяснение этого. – Mohamad

10

вы можете сделать это следующим образом:

expect(current_path).to eql(new_app_user_registration_path) 
3

Вот хаком решение, которое я нашел

# spec/features/user_confirmation_feature.rb 

feature 'User confirmation' do 
    scenario 'provide confirmation and redirect' do 
    visit "https://stackoverflow.com/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 
+0

Это помогает, если ваше перенаправление оказывается внешней ссылкой –

2

Rspec 3:

Самый простой способ проверить текущий путь с :

expect(page).to have_current_path('/login?status=invalid_token')

have_current_path имеет преимущество по сравнению с этим подходом:

expect(current_path).to eq('/login')

, потому что вы можете включить параметры запроса.

+1

, что является отличием от expect (current_path) .to eq ('/ login? Status = invalid_token')? – sekmo

Смежные вопросы