代码之家  ›  专栏  ›  技术社区  ›  catinahat

RSpec测试未通过我的用户控制器`预期响应为<3XX:重定向>,但为<200:正常>`

  •  0
  • catinahat  · 技术社区  · 7 年前

    在查看了有类似错误消息的人的帖子后,我仍然不明白为什么我的RSpec测试不能通过。运行规范时,我收到以下错误消息:

    失败:

    1) UsersController在用户未登录时获取#显示重定向 登录的步骤 失败/错误:预期(响应)。重定向到(new\u user\u session\u path)

       Expected response to be a <3XX: redirect>, but was a <200: OK>
       Response body:
     # ./spec/model/user_spec.rb:21:in `block (4 levels) in <top (required)>'
    

    在0.25988秒内完成(加载文件需要5.02秒)5 示例,1故障

    失败的示例:

    rspec公司/规格/型号/用户\u规格rb:19#UsersController获取#显示 用户未登录重定向到登录“


    这是我的user\u spec文件:

    require 'rails_helper'
    
    describe UsersController, type: :controller do
      let(:user) { User.create!(email: 'test@example.com', password: '1234567890') }
    
      describe 'GET #show' do
    
        context 'when a user is logged in' do
            before do
                sign_in user
            end
            it 'loads correct user details' do
                get :show, params: { id: user.id }
                expect(assigns(:user)).to eq user
            end
        end
    
        context 'when a user is not logged in' do
          it 'redirects to login' do
            get :show, params: { id: user.id }
            expect(response).to redirect_to(new_user_session_path)
          end
        end
      end
    
    end
    

    我的rails\u助手。rb:

    # This file is copied to spec/ when you run 'rails generate rspec:install'
    require 'spec_helper'
    
    ENV['RAILS_ENV'] ||= 'test'
      require File.expand_path('../../config/environment', __FILE__)
      # Prevent database truncation if the environment is production
      abort("The Rails environment is running in production mode!") if Rails.env.production?
      require 'rspec/rails'
      # Add additional requires below this line. Rails is not loaded until this point!
    
      # note: require 'devise' after require 'rspec/rails'
      require 'devise'
    
    RSpec.configure do |config|
      # For Devise >= 4.1.0
      config.include Devise::Test::ControllerHelpers, type: :controller
      # Use the following instead if you are on Devise <= 4.1.1
      # config.include Devise::TestHelpers, :type => :controller
    end
    
      # Requires supporting ruby files with custom matchers and macros, etc, in
      # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
      # run as spec files by default. This means that files in spec/support that end
      # in _spec.rb will both be required and run as specs, causing the specs to be
      # run twice. It is recommended that you do not name files matching this glob to
      # end with _spec.rb. You can configure this pattern with the --pattern
      # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
      #
      # The following line is provided for convenience purposes. It has the downside
      # of increasing the boot-up time by auto-requiring all files in the support
      # directory. Alternatively, in the individual `*_spec.rb` files, manually
      # require only the support files necessary.
      #
      # Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
    
      # Checks for pending migrations and applies them before tests are run.
      # If you are not using ActiveRecord, you can remove this line.
    
    ActiveRecord::Migration.maintain_test_schema!
    
    RSpec.configure do |config|
      # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
      config.fixture_path = "#{::Rails.root}/spec/fixtures"
    
      # If you're not using ActiveRecord, or you'd prefer not to run each of your
      # examples within a transaction, remove the following line or assign false
      # instead of true.
      config.use_transactional_fixtures = true
    
      # RSpec Rails can automatically mix in different behaviours to your tests
      # based on their file location, for example enabling you to call `get` and
      # `post` in specs under `spec/controllers`.
      #
      # You can disable this behaviour by removing the line below, and instead
      # explicitly tag your specs with their type, e.g.:
      #
      #     RSpec.describe UsersController, :type => :controller do
      #       # ...
      #     end
      #
      # The different available types are documented in the features, such as in
      # https://relishapp.com/rspec/rspec-rails/docs
      config.infer_spec_type_from_file_location!
    
      # Filter lines from Rails gems in backtraces.
      config.filter_rails_from_backtrace!
      # arbitrary gems may also be filtered via:
      # config.filter_gems_from_backtrace("gem name")
    
    end
    

    My users\u控制器:

     class UsersController < ApplicationController
        before_action :set_user, only: [:show, :edit, :update, :destroy]
        before_action :authenticate_user!
        before_action :authenticate_user!, except: [:show, :index]
        load_and_authorize_resource
      # GET /users
      # GET /users.json
      def index
        @users = User.all
      end
    
      # GET /users/1
      # GET /users/1.json
      def show
      end
    
      # GET /users/new
      def new
        @user = User.new
      end
    
      # GET /users/1/edit
      def edit
      end
    
      # POST /users
      # POST /users.json
      def create
        @user = User.new(user_params)
    
        respond_to do |format|
          if @user.save
            format.html { redirect_to @user, notice: 'User was successfully created.' }
            format.json { render :show, status: :created, location: @user }
          else
            format.html { render :new }
            format.json { render json: @user.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # PATCH/PUT /users/1
      # PATCH/PUT /users/1.json
      def update
        respond_to do |format|
          if @user.update(user_params)
            format.html { redirect_to @user, notice: 'User was successfully updated.' }
            format.json { render :show, status: :ok, location: @user }
          else
            format.html { render :edit }
            format.json { render json: @user.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # DELETE /users/1
      # DELETE /users/1.json
      def destroy
        @user.destroy
        respond_to do |format|
          format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
          format.json { head :no_content }
        end
      end
    
      private
        # Use callbacks to share common setup or constraints between actions.
        def set_user
          @user = User.find(params[:id])
        end
    
        # Never trust parameters from the scary internet, only allow the white list through.
        def user_params
          params.require(:user).permit(:first_name, :last_name)
        end
    end
    

    和路线:

    Rails.application.routes.draw do
      devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout' }
    
      resources :products do
        resources :comments
      end
      resources :users
    
      post 'simple_pages/thank_you'
    
      get 'simple_pages/about'
    
      get 'simple_pages/contact'
    
      get 'simple_pages/thank_you'
    
      get 'simple_pages/index'
        root "simple_pages#landing_page"
    
        resources :orders, only: [:index, :show, :create, :destroy]
    
      # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
    end
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Manishh    7 年前

    您的问题是由于2

    before_action :authenticate_user!
    before_action :authenticate_user!, except: [:show, :index]
    

    您的筛选器正在被第二次调用覆盖。在你的第二次通话中 expect show 这将允许用户无需登录即可访问页面,因此您的测试不会通过,因为它不会重定向到登录页面。只需删除 before_action :authenticate_user!, except: [:show, :index] 从控制器,它将为您的测试工作。