Ruby on rails Rspec NoMethodError:未定义的方法'errors\u on'

Ruby on rails Rspec NoMethodError:未定义的方法'errors\u on',ruby-on-rails,rspec,tdd,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 befor

我正在测试地址模型中城市属性条目的有效性。我的型号规格如下

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)>'
我的spec_助手中包含了rspec集合匹配器,因此我不明白为什么会出现此错误

My spec_helper.rb

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

我的.rspec

我也改变了我的立场

require 'rspec/collection_matchers'
到rails_helper.rb,但再次运行测试套件会出现相同的错误

rails_helper.rb

My spec_helper.rb为空,仅包含以下块:

RSpec.configure do |config|
end

我使用的是Rails 4.1.0、rspec 3.0.0和rspec-collection\u matchers 1.0.0,没有看到回购协议,这只是基于信息的猜测。我认为这是一个装载顺序问题

看起来您是在spec\u助手中加载rspec/collection\u匹配器,而不是在rails\u助手中加载。如果您使用的是新的默认配置,-require spec\u helper位于.rspec文件中。运行rspec时,很早就需要spec\u助手。发生这种情况时,需要rspec/collection\u匹配器。但是,此时还没有加载rails\u helper。不幸的是,这也意味着包括ActiveModel在内的大多数ActiveSupport尚未加载。这还意味着Rails自动加载功能尚未加载,因此在引用它们时不会对其进行定义

综上所述,ActiveModel的检查返回false。不会加载错误

尝试将require移动到rails\u帮助程序中

关于隔离测试的说明:

如果您打算单独进行更快的测试,我的建议是:

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

将所列出的requires从spec\u helper移动到rails\u helper中,这些都是特定于rails的,不属于spec\u helper,因为rails没有加载到那里

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


你的规范需要rails\u helper,但是你把require'rspec/collection\u matchers'行放在了spec\u helper中-你的rails\u helper文件需要'spec\u helper'吗?@DylanMarkow是的,我的rails\u helper.rb文件需要spec\u helper我已经把所有需要的东西都移到了rails\u helper,正如你建议的那样,但是我仍然得到了错误,我在问题中也包括了rails\u helper和spec\u helper文件内容,这是同样的问题。在加载rails之前,您需要集合匹配器。将requires移动到需要“rspec/rails”之后
--color
--require spec_helper
require 'rspec/collection_matchers'
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
RSpec.configure do |config|
end