RSpec测试单独传递,但在一起运行时失败

时间:2017-10-21 06:40:53

标签: ruby-on-rails rspec capybara rspec-rails

在我的code_controller_spec.rb中,当我在code_controller_spec.rb中运行测试时,我的测试通过了。但是,当我运行套件时,只有createeditupdate测试在code_controller_spec.rb内失败。我真的不知道从哪里开始,我真的不知道为什么我的测试在一起跑时失败了。我有config.use_transactional_fixtures = false并且正在使用database_cleaner。我的应用程序在本地使用以下操作正常工作,我在创建或更新帖子时没有收到任何错误。如果您需要其他信息,请与我们联系。

当我运行套件时,我得到的失败是:

1) CodesController admin pages #create posts a new code post
     Failure/Error:
       post :create, params: {
         code: { 
           created_at: Date.today, 
           title: "Code things", 
           content: "The content of the code post",
           user_id: user.id
         }
       }

     ActionController::UrlGenerationError:
       No route matches {:action=>"create", :code=>{:created_at=>Fri, 20 Oct 2017, :title=>"Code things", :content=>"The content of the code post", :user_id=>1}, :controller=>"codes"}

2)  CodesController admin pages #edit edits a code post
     Failure/Error: get :edit, params: { id: code }

     ActionController::UrlGenerationError:
       No route matches {:action=>"edit", :controller=>"codes", :id=>#<Code id: 1, title: "Code post title", content: "Coding speak that not everyone can understand...", created_at: "2017-10-20 00:00:00", updated_at: "2017-10-21 06:05:27", user_id: 2>}

3) CodesController admin pages #update updates a code post
     Failure/Error: put :update, params: { id: code, code: code2 }

     ActionController::UrlGenerationError:
       No route matches {:action=>"update", :code=>{:title=>"Updated title", :content=>"Updated content"}, :controller=>"codes", :id=>#<Code id: 1, title: "Code post title", content: "Coding speak that not everyone can understand...", created_at: "2017-10-20 00:00:00", updated_at: "2017-10-21 06:05:27", user_id: 2>}

我的spec/controllers/user/codes_controller_spec.rb

RSpec.describe User::CodesController, type: :controller do

  let!(:user) { User.create(email: "user@example.com", password: "password") }
  let!(:code) { FactoryGirl.create(:code) }

  before do
    sign_in_as user
    expect(response).to have_http_status(:success)
  end

  describe "admin pages" do
    render_views

    context "#create" do
      it "posts a new code post" do
        post :create, params: {
          code: { 
            created_at: Date.today, 
            title: "Code things", 
            content: "The content of the code post",
            user_id: user.id
          }
        }
        expect(response).to redirect_to user_codes_path
        expect(flash[:success]).to eq "Post created successfully."
      end
    end

    context "#edit" do
      it "edits a code post" do
        get :edit, params: { id: code }
        expect(response).to render_template :edit
      end
    end

    context "#update" do
      let(:code2) do 
        { title: "Updated title", content: "Updated content" }
      end
      it "updates a code post" do
        put :update, params: { id: code, code: code2 }
        code.reload
        expect(response).to redirect_to user_code_path(code)
        expect(code.title).to eq code2[:title]
        expect(code.content).to eq code2[:content]
        expect(flash[:success]).to eq "Post updated successfully."
      end
    end
  end
end

我的spec/factories/post_factories.rb

FactoryGirl.define do
  factory :code do
    created_at Date.today
    title "Code post title"
    content "Coding speak that not everyone can understand..."

    association :user, factory: :user
  end

  factory :life do
    created_at Date.today
    title "Life post title"
    content "The world moves in mysterious ways; whether we want it to..."

    association :user, factory: :user
  end
end

我运行rspec --seed 123 --bisect然后运行它的输出,但我的所有测试都通过了。我应该提到我对--bisect很新。

这是rspec --seed 123 --bisect输出,当我运行时,我的所有测试都会通过。

rspec ./spec/controllers/user/codes_controller_spec.rb[1:1:1:1,1:1:2:1,1:1:3:1,1:1:4:1,1:1:5:1] ./spec/controllers/user/lives_controller_spec.rb[1:1:1,1:1:2] ./spec/features/admin_create_posts_spec.rb[1:1,1:2,1:3,1:4] ./spec/features/admin_edit_post_spec.rb[1:1,1:2,1:3] ./spec/features/clearance/user_signs_out_spec.rb[1:1] ./spec/features/clearance/visitor_resets_password_spec.rb[1:1,1:2,1:3,1:4,1:5,1:6] ./spec/features/clearance/visitor_signs_in_spec.rb[1:1,1:2,1:3,1:4,1:5,1:6,1:7,1:8] ./spec/features/clearance/visitor_signs_up_spec.rb[1:1,1:2,1:3,1:4,1:5,1:6,1:7,1:8] ./spec/features/clearance/visitor_updates_password_spec.rb[1:1,1:2,1:3] ./spec/features/homepage_spec.rb[1:1,1:2] ./spec/features/login_users_spec.rb[1:1,1:2] ./spec/features/logout_user_spec.rb[1:1] ./spec/features/showing_all_posts_spec.rb[1:1,1:2] ./spec/helpers/codes_helper_spec.rb[1:1] ./spec/helpers/lives_helper_spec.rb[1:1] ./spec/helpers/user/codes_helper_spec.rb[1:1] ./spec/helpers/user/lives_helper_spec.rb[1:1] ./spec/helpers/users_helper_spec.rb[1:1] ./spec/helpers/welcome_helper_spec.rb[1:1] ./spec/models/code_spec.rb[1:1] ./spec/models/life_spec.rb[1:1]

我在database_cleaner

中的rails_helper.rb个配置
require database_cleaner

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  # config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.before(:all) do
    FactoryGirl.reload
  end

  # 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.before(:suite) do
    if config.use_transactional_fixtures?
      raise(<<-MSG)
        Delete line `config.use_transactional_fixtures = true` from rails_helper.rb (or set it to false) to prevent uncommitted transactions being used in JavaScript-dependent specs.
                During testing, the app-under-test that the browser driver connects to uses a different database connection to the database connection used by the spec. The app's database connection would not be able to access uncommitted transaction data setup over the spec's database connection.
      MSG
    end
    DatabaseCleaner.clean_with(:truncation)
  end  

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, type: :feature) do
    # :rack_test driver's Rack app under test shares database connection
    # with the specs, so continue to use transaction strategy for speed.
    driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test

    if !driver_shares_db_connection_with_specs
      # Driver is probably for an external browser with an app under test that does *not*
      # share a database connection with the specs, so use truncation strategy.
      DatabaseCleaner.strategy = :truncation
    end
  end

  # adds this from
  # https://stackoverflow.com/questions/37753251/actionmailer-not-delivering-confirmation-emails-in-test-environment-rails-4
  config.before(:each, truncation: true) do 
    Database::Cleaner.strategy = :truncation 
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.append_after(:each) do
    DatabaseCleaner.clean
  end
end

已更新 rails routes

的输出
Prefix Verb   URI Pattern                             Controller#Action
              root GET    /                                       welcome#index
         passwords POST   /passwords(.:format)                    clearance/passwords#create
      new_password GET    /passwords/new(.:format)                clearance/passwords#new
           session POST   /session(.:format)                      clearance/sessions#create
edit_user_password GET    /users/:user_id/password/edit(.:format) clearance/passwords#edit
     user_password PATCH  /users/:user_id/password(.:format)      clearance/passwords#update
                   PUT    /users/:user_id/password(.:format)      clearance/passwords#update
                   POST   /users/:user_id/password(.:format)      clearance/passwords#create
             users POST   /users(.:format)                        clearance/users#create
           sign_in GET    /sign_in(.:format)                      clearance/sessions#new
          sign_out DELETE /sign_out(.:format)                     clearance/sessions#destroy
                   GET    /sign_out(.:format)                     clearance/sessions#destroy
           sign_up GET    /sign_up(.:format)                      clearance/users#new
        user_lives GET    /user/lives(.:format)                   user/lives#index
                   POST   /user/lives(.:format)                   user/lives#create
     new_user_life GET    /user/lives/new(.:format)               user/lives#new
    edit_user_life GET    /user/lives/:id/edit(.:format)          user/lives#edit
         user_life GET    /user/lives/:id(.:format)               user/lives#show
                   PATCH  /user/lives/:id(.:format)               user/lives#update
                   PUT    /user/lives/:id(.:format)               user/lives#update
                   DELETE /user/lives/:id(.:format)               user/lives#destroy
        user_codes GET    /user/codes(.:format)                   user/codes#index
                   POST   /user/codes(.:format)                   user/codes#create
     new_user_code GET    /user/codes/new(.:format)               user/codes#new
    edit_user_code GET    /user/codes/:id/edit(.:format)          user/codes#edit
         user_code GET    /user/codes/:id(.:format)               user/codes#show
                   PATCH  /user/codes/:id(.:format)               user/codes#update
                   PUT    /user/codes/:id(.:format)               user/codes#update
                   DELETE /user/codes/:id(.:format)               user/codes#destroy
             lives GET    /lives(.:format)                        lives#index
              life GET    /lives/:id(.:format)                    lives#show
             codes GET    /codes(.:format)                        codes#index
              code GET    /codes/:id(.:format)                    codes#show

1 个答案:

答案 0 :(得分:1)

我认为这是一个自动加载问题。如果您的::CodesControllerUsers::CodesController之前加载,那么Users::CodesController的规范实际上正在使用::CodesController,因此无法创建正确的路由。单独运行时,正确的类是自动加载的,一切正常。要解决此问题,需要在规范开头提供正确的类。

# spec/controllers/user/codes_controller_spec.rb

require 'user/codes_controller'
...

# spec/controllers/codes_controller_spec.rb

require 'codes_controller'
...