运行rspec请求规范找不到存在的记录

时间:2018-06-21 20:30:39

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

我正在为我的一个项目使用Rails 5(Ruby 2.3.3)。我已经使用Capybara(capybara-wekbit)和RSpec编写了一个测试。

我正在使用请求规范测试控制器动作。这是控制器

class TimelineController < ApplicationController
  before_action :set_child
  before_action :authenticate_user!

  def index    
  end

  private
  def set_child
    @child = Child.find(params[:child_id])
  end
end

这是测试

RSpec.describe "Timeline", type: :request do
  it 'can visit the child timeline path', js: true do
    child = FactoryGirl.create(:valid_child)
    sign_in child.caregiver.user
    p child
    visit child_timeline_path(child)
  end
end

p child行显示以下内容

#<Child id: 1, first_name: nil, last_name: nil, dob: "2018-06-21 00:00:00", caregiver_id: 1, doctor_id: 1, preferred_name: nil, gender: nil, street: nil, city: nil, province: nil, postal: nil, country: nil, email: nil, caregiver_relationship: nil, phone: nil, created_at: "2018-06-21 20:21:16", updated_at: "2018-06-21 20:21:16", avatar: nil, time_zone: "Pacific Time (US & Canada)", other_relationship: nil>

但是,当RSpec调用visit child_timeline_path(child)时,测试失败并显示以下错误:

  1) Timeline can visit the child timeline path
     Failure/Error: @child = Child.find(params[:child_id])

     ActiveRecord::RecordNotFound:
       Couldn't find Child with 'id'=1

我看到带有ID的子记录。但是,rspec无法找到记录。

这是子工厂(FactoryGirl)

FactoryGirl.define do
  factory :valid_child, class: "Child" do |f|
    f.association :doctor
    f.association :caregiver
    f.dob Date.today
  end
end

如果有帮助,这是spec_helper.rb

require 'capybara/rspec'

Dir["./spec/support/**/*.rb"].sort.each {|f| require f}

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
  config.include Capybara::DSL
  config.include Devise::Test::IntegrationHelpers, type: :request

  Capybara.javascript_driver = :webkit

  # 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|
      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|
    mocks.verify_partial_doubles = true
  end

  # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
  # have no way to turn it off -- the option exists only for backwards
  # compatibility in RSpec 3). It causes shared context metadata to be
  # inherited by the metadata hash of host groups and examples, rather than
  # triggering implicit auto-inclusion in groups with matching metadata.
  config.shared_context_metadata_behavior = :apply_to_host_groups

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
end

1 个答案:

答案 0 :(得分:2)

DatabaseCleaner.strategy = :transaction表示被测应用程序和被测应用程序需要共享相同的数据库连接才能查看已创建的记录。不幸的是,在各个线程之间并没有真正支持的Rails 5(在Rails 5.1+中已修复,根本不需要使用database_cleaner)。这意味着在运行js: true功能测试(在单独的线程中运行应用程序)时,您需要将策略更改为:truncation或:deletion。建议的DatabaseCleaner配置准确显示了所需的内容-https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example