这是一个水豚功能测试。我的控制器中没有为根页面设置的before_action过滤器,所以我完全被这个难过了。其他人有同样的问题吗?
导致错误的行只是
require 'rails_helper'
def manually_create_user
visit new_user_registration_path
fill_in('user_first_name', :with => 'Test')
fill_in('user_last_name', :with => 'User')
fill_in('user_email', :with => 'testuser@email.com')
fill_in('user_password', :with => 'testuser')
fill_in('user_password_confirmation', :with => 'testuser')
click_button('Sign up')
end
def create_user_and_login_as(type)
user = FactoryGirl.create(type)
visit(new_user_session_path)
fill_in('user_email', :with => user.email)
fill_in('user_password', :with => user.password)
click_button('Log in')
end
describe 'with users and roles' do
context "if user is not an admin" do
it "makes sure Login/Logout works" do
visit(root_path)
click_link("Sign up")
fill_in('user_email', :with => "testuser@email.com")
fill_in('user_first_name', :with => "Test")
fill_in('user_last_name', :with => "User")
fill_in('user_password', :with => "password")
fill_in('user_password_confirmation', :with => "password")
click_button "Sign up"
expect(current_path).to eq(root_path)
expect(page).to have_content('Welcome! You have signed up successfully.')
end
end
end
非常奇怪。
此外,当单独运行此测试时,它会通过,但在运行整个测试套件时,它会因InfiniteRedirectError而失败。
user_and_role_spec.rb:
class StaticPagesController < ApplicationController
before_action :an_admin?, only: [:admin]
def home
@testimonials = Testimonial.all
end
def admin
@groups = Group.all
@users = User.all
@students = Student.all
@teachers = Teacher.all
end
private
def an_admin?
unless signed_in? && (current_user.admin == true)
redirect_to root_path, notice: "You have to be a signed-in admin to view the admin page"
end
end
end
static_pages_controller.rb:
Rails.application.routes.draw do
resources :materials
root 'static_pages#home'
devise_for :users, :controllers => { registrations: 'registrations' }
get 'admin' => 'static_pages#admin'
resources :groups
resources :users
resources :students
resources :teachers
resources :testimonials
post 'assign_to_group' => 'students#assign_to_group' # Could have been 'patch', but default in the controller method is 'post', so I left the method as default and changed this route to 'post'. Doesn't NEED to be patch.
post 'remove_from_group' => 'students#remove_from_group'
post 'unassign_teacher' => 'groups#unassign_teacher'
post 'assign_as_student' => 'teachers#assign_as_student'
post 'assign_as_teacher' => 'students#assign_as_teacher'
post 'add_student' => 'groups#add_student'
post 'remove_student_from_group' => 'groups#remove_student_from_group'
end
routes.rb中:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
require 'database_cleaner'
require 'devise'
# Add additional requires below this line. Rails is not loaded until this point!
# 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 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!
config.include Devise::TestHelpers, :type => :controller
Capybara.register_driver :rack_test do |app|
Capybara::RackTest::Driver.new(app, :respect_data_method => true, :redirect_limit => 20)
end
end
rails_helper.rb:
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.
config.expect_with :rspec do |expectations|
# This option will default to `true` in RSpec 4. It makes the `description`
# and `failure_message` of custom matchers include text for helper methods
# defined using `chain`, e.g.:
# be_bigger_than(2).and_smaller_than(4).description
# # => "be bigger than 2 and smaller than 4"
# ...rather than:
# # => "be bigger than 2"
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
# rspec-mocks config goes here. You can use an alternate test double
# library (such as bogus or mocha) by changing the `mock_with` option here.
config.mock_with :rspec do |mocks|
# Prevents you from mocking or stubbing a method that does not exist on
# a real object. This is generally recommended, and will default to
# `true` in RSpec 4.
mocks.verify_partial_doubles = true
end
end
spec_helper.rb:
Started GET "/" for 127.0.0.1 at 2015-05-19 13:37:49 +0200
Processing by StaticPagesController#home as HTML
Redirected to http://www.example.com/
Filter chain halted as :an_admin? rendered or redirected
Completed 302 Found in 6ms (ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2015-05-19 13:37:49 +0200
Processing by StaticPagesController#home as HTML
Redirected to http://www.example.com/
Filter chain halted as :an_admin? rendered or redirected
Completed 302 Found in 7ms (ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2015-05-19 13:37:49 +0200
Processing by StaticPagesController#home as HTML
Redirected to http://www.example.com/
Filter chain halted as :an_admin? rendered or redirected
test.log中:
controller.class.skip_before_action :an_admin?
......等等
对我来说,这说明我的static_pages_controller中的before_action被踢了,但我不明白为什么会这样,给定an_admin?方法的代码?
我可能正在接近解决这个问题:在运行完整的测试套件时,在user_and_role_spec之前运行static_controller_spec。当我禁用static_controller_spec时,运行整个测试套件时,user_and_role_spec测试运行时没有错误。罪魁祸首似乎是这一行:
require "rails_helper.rb"
describe StaticPagesController do
describe "GET #home" do
it "renders the :home view" do
get :home
expect(response).to render_template :home
end
end
describe "GET #admin" do
it "renders the :admin view" do
# This is line 14. The next line is intended to disable the :an_admin? before_action in the controller
controller.class.skip_before_action :an_admin?
get :admin
expect(response).to render_template :admin
# The next line is intended to reverse line 15
controller.class.before_action :an_admin?
end
it "requires user to be signed_in"
it "requires user to be an admin"
end
end
这一行在static_controller_spec:
中{{1}}
我想禁用此测试的before_action。说实话,我真的不明白那条线 - 它是从某个地方直接复制/粘贴。它似乎搞乱了我的user_and_role_spec测试,但我不明白为什么。有什么想法吗?
答案 0 :(得分:0)
在您的user_and_role_spec.rb中,在结束结束end
后您还有一个def create_user_and_login_as(type)
。
您需要在规范底部有两个end
才能关闭describe 'with users and roles' do
和context "if user is not an admin" do
。
在您的routes.rb中,您需要在底部end
关闭Rails.application.routes.draw do
我不确定您是否只是粘贴它们,但它在您的应用程序中确实很重要,并且当您发布代码时它确实很重要。
答案 1 :(得分:0)
解决:
参考我原来的帖子中的更新,我只是完全删除了static_pages_controller_spec中的那两个controller.class行,并且整个测试套件都通过了(感谢上帝!)。当然,它确实让我想知道为什么我首先在那里有那些线 - 我根本无法记住。
但是,这仍然有点神秘,这就是为什么我开始this other thread试图揭示它的原因。我知道我在这里要求相当多的手持,但任何帮助都会非常感激。我自己也做了很多学习,但也很高兴得到别人的意见。