【问题标题】:Rails failure to load shoulda-matchers 3.1.1 gem, undefined method `allow_value' for #<RSpecRails 无法加载 shoulda-matchers 3.1.1 gem,#<RSpec 的未定义方法“allow_value”
【发布时间】:2016-08-22 09:40:19
【问题描述】:

运行 rspec 测试时未加载“should-matchers”gem。

错误: NoMethodError: undefined method 'allow_value' for #&lt;RSpec::ExampleGroups::Contact::ActiveModelValidationss:0x007fef1021b310&gt;

正在使用的版本: Ruby 2.2.2 Rails 4.2.1 shoulda-matchers 3.1.1

宝石文件:

source 'https://rubygems.org'

gem 'rails', '4.2.1'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc

group :development, :test do
  gem 'byebug'
  gem 'rspec-rails', '~> 3.0'
  gem 'factory_girl_rails'
  gem 'shoulda-matchers', '~> 3.1'
  gem 'web-console', '~> 2.0'
  gem 'spring'
  gem 'rubocop', require: false
end

rails_helper.rb:

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!

  Shoulda::Matchers.configure do |config|
    config.integrate do |with|
      with.test_framework :rspec
      with.library :active_record
      with.library :rails
    end
  end
end

spec_helper.rb:

RSpec.configure do |config|
  require 'factory_girl_rails'
  require 'shoulda/matchers'
  config.include FactoryGirl::Syntax::Methods
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end
  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
end

contact_spec.rb:

require 'spec_helper'

describe Contact do

  FactoryGirl.define do
    factory :contact do
      first_name "Alice"
      last_name  "Bob"
      email_address "alicebob@example.com"
      phone_number "555-555-5555"
      company_name "ExampleCompany"
    end
  end

  it "has a valid factory" do
    expect(build(:contact)).to be_valid
  end

  describe "ActiveModel validations" do
    it { expect(:contact).to allow_value("alice_bob@example.com").for(:email_address) }
  end
end

对不起所有的代码。请注意,我使用的是 3.1.1 版的 shoulda-matchers 并且不再需要向 gemfile 添加“require:false”,如此处所述https://robots.thoughtbot.com/shoulda-matchers-3-0

我也尝试在 Gemfile 中将 shoulda-matchers 添加到它自己的测试环境中,如下所示,但没有发现任何变化

group :test do
  gem 'shoulda-matchers', '~> 3.1'
end

我在网上查看并发现在我的情况下不起作用的解决方案存在类似问题。任何帮助或建议都会很棒!

【问题讨论】:

  • 您的问题解决了吗?

标签: ruby-on-rails-4 testing rspec rspec-rails shoulda


【解决方案1】:

在我的例子中,问题是被测试的类不是ActiveRecord项,所以shoulda默认没有加载allow_value等方法。

解决方案是在_spec.rb 文件中添加type: :model

RSpec.describe MyTestedClass, type: :model do
  ...
end

【讨论】:

  • 这是我的自定义验证器规范的情况,与许多其他来源建议的加载无关。
【解决方案2】:

应该让你再次变绿的解决方法是改变:

it { expect(:contact).to allow_value("alice_bob@example.com").for(:email_address) }

it { expect(build(:contact)).to allow_value("alice_bob@example.com").for(:email_address) }

与您的第一个测试相同,因为您的第二个测试需要符号 :contactallow_value,而不是在您的工厂中创建的对象。

此外,我建议将您的工厂定义移动到 spec/factories/contact.rb 下的自己的文件中,而不是在您的规范中内联,并在 let 方法中记住联系人对象,这样您就会有一个看起来像:

require 'spec_helper'

describe Contact do
  let(:contact) { build(:contact) }

  it "has a valid factory" do
    expect(contact).to be_valid
  end

  describe "ActiveModel validations" do
    it { expect(contact).to allow_value("alice_bob@example.com").for(:email_address) }
  end
end

【讨论】:

    猜你喜欢
    • 2016-03-13
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多