Я обновляю устаревший проект до rails 5, и среди тестов rspec, которые не работают, у меня есть один, который говорит:

 Failure/Error: expect(response).to be_redirect
   expected `#<ActionDispatch::TestResponse:0x00007fbe5fde51f0 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::...ch::Http::Headers:0x00007fbe5fdde9e0 @req=#<ActionController::TestRequest:0x00007fbe5fde5358 ...>>>>.redirect?` to return true, got false
 # ./spec/controllers/search_controller_spec.rb:86:in `block (3 levels) in <top (required)>'

Я использую devise gem для аутентификации клиентов.
Испытания следующие:

describe SearchController do

  before(:each) do
    @client = FactoryGirl.create(:client)
  end

  describe "authenticated search" do
    # a bunch of tests
  end

  describe "unauthenticated search" do
    it "requires a user to be authenticated" do
      get :search, params: { q: "tec" }, format: :json

      expect(response).to be_redirect  # FAILING HERE
    end
  end
end

Если я запустил тест вручную и перейду на /search?q=tec, я буду перенаправлен на страницу sign_in. search_controller.rb имеет before_action :authenticate_client!

Я пробовал добавить sign_out @client перед поиском, но это не сработало. Также пробовал current_client.reload, но не распознал current_client.

В тестах аутентифицированного поиска есть вызов stub_authenticate_client, который имеет следующий код:

  def stub_authenticate_client(client)
    allow(request.env['warden']).to receive(:authenticate!) { client }
    allow(controller).to receive(:current_client) { client }
  end

В случае, если это полезно для решения этой проблемы.

Я также пробовал создать такой метод stub_logout_client:

  def stub_logout_client(client)
    allow(request.env['warden']).to receive(:authenticate!) { nil }
    allow(controller).to receive(:current_client) { nil }
  end

И вызывает его в начале теста, но он все еще проходит before_action authenticate_client!

Также попробовал то, что было предложено здесь, но не сработало

Контроллер поиска, который тестируется:

class SearchController < ClientApplicationController
  before_action :authenticate_client!

  def search
    limit = params[:limit] ? params[:limit].to_i : 10
    query = params[:q].to_s.downcase.strip

    results = {}

    if params[:report]
      results[:this_report] = Report.where("SOME QUERY")
    end

    render json: results
  end
end

Спасибо!

2
marimaf 5 Окт 2018 в 01:26

1 ответ

Лучший ответ

Проблема связана с проверкой be_redirect. Изменил тест для проверки содержимого в ответе и решил его, например:

describe "unauthenticated search" do
    it "requires a user to be authenticated" do
      get :search, params: { q: "tec" }, format: :json
      expect(response.body).to have_content("content from the page I render")
    end
  end
1
marimaf 11 Окт 2018 в 13:22