Rspec NoMethodError:未定义的方法`errors_on'

时间:2014-08-04 13:28:19

标签: ruby-on-rails rspec tdd

我正在测试地址模型中城市属性的输入验证。我的型号规格如下

require 'rails_helper'

RSpec.describe Address, :type => :model do
  before(:each) do
    @valid_attributes = {
      street: 'rock avenue',
      city: 'MSA',
      zip: '00100',
      person_id: 1
    } # runs before each it block
  end

  context "Validations" do
    it 'must have a city' do
      a = Address.new
      expect(a.errors_on(:city)).not_to be_empty
    end
  end
end

当我运行规范时,我收到以下错误

  1) Address Validations must have a city
     Failure/Error: expect(a.errors_on(:city)).not_to be_empty
     NoMethodError:
       undefined method `errors_on' for #<Address:0xd844538>
     # ./spec/models/address_spec.rb:19:in `block (3 levels) in <top (required)>'

我的测试宝石在我的Gemfile中设置如下

group :development, :test do
  gem 'rspec-rails'
  gem 'factory_girl_rails', :require => false
end

group :test do
  gem 'capybara'
  gem 'guard'
  gem 'guard-rspec'
  gem 'libnotify'
  gem 'rspec-collection_matchers'
end

我在我的spec_helper中包含了rspec集合匹配器,因此我不明白为什么会出现此错误

我的 spec_helper.rb

require 'capybara/rspec' 
require 'factory_girl_rails'
require 'rspec/collection_matchers'

但是我可以看到方法 errors_on 已经在rspec-collection_matchers gem中定义,如图所示here

我的 .rspec

--color
--require spec_helper

我也改变了

的位置
require 'rspec/collection_matchers'

rails_helper.rb ,但再次运行测试套件会出现同样的错误

rails_helper.rb

ENV["RAILS_ENV"] ||= 'test'
require 'rspec/collection_matchers'
require 'capybara/rspec'
require 'factory_girl_rails'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.include Capybara::DSL
  config.include FactoryGirl::Syntax::Methods
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
end

我的 spec_helper.rb 为空,只有以下块:

RSpec.configure do |config|
end

我使用的是Rails 4.1.0,rspec 3.0.0和rspec-collection_matchers 1.0.0

1 个答案:

答案 0 :(得分:0)

没有看到回购,这只是基于信息的猜测。我认为这是一个加载顺序问题。

您好像在rspec/collection_matchers加载spec_helper,而不是rails_helper。如果您使用的是新的默认配置,则--require spec_helper文件中会显示.rspec。运行rspec时,这很早就需要spec_helper。当发生这种情况时,需要rspec/collection_matchers。但是,此时rails_helper尚未加载。不幸的是,这也意味着大多数ActiveSupport包括ActiveModel尚未加载。这也意味着尚未加载Rails自动加载功能,因此在引用它们时不会定义它们。

所有这一切,ActiveModel here的检查会返回false。哪个不加载errors_on

尝试将需求移至rails_helper

关于单独测试的注意事项:

如果你想进行更快速的测试,这是我的建议:

  • spec_helper应该保持非常小和轻量级,这意味着大多数情况下你不应该向它添加任何require声明

  • 将您从spec_helper列出的要求移至rails_helper,这些要求主要是Rails,不属于spec_helper,因为Rails未加载

    < / LI>
  • 如果您需要访问不需要Rails的规范中的其他rspec/collection_matchers功能,那么只需将require 'rspec/collection_matchers'添加到spec文件的顶部即可; Ruby将处理确保它只加载一次