【问题标题】:Rspec NoMethodError: undefined method `errors_on'Rspec NoMethodError:未定义的方法“errors_on”
【发布时间】:2014-09-26 23:52:26
【问题描述】:

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

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)>'

我的测试 gem 在我的 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

【问题讨论】:

  • 您的规范需要rails_helper,但您将require 'rspec/collection_matchers' 行放入spec_helper -- 您的rails_helper 文件是否需要'spec_helper'?
  • @DylanMarkow 是的,我的 rails_helper.rb 文件需要 spec_helper

标签: ruby-on-rails rspec tdd


【解决方案1】:

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

看起来您正在将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

尝试将 require 移至 rails_helper

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

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

  • spec_helper 应该保持最小和轻量级,这意味着在大多数情况下您不应该向其中添加任何 require 声明

  • 将您列出的需求从spec_helper 移动到rails_helper,这些需求大多是特定于Rails 的,不属于spec_helper,因为Rails 没有在那里加载

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

【讨论】:

  • 按照您的建议,我已将所有需要的内容移至 rails_helper,但仍然出现错误
  • 我的问题中还包含了 rails_helper 和 spec_helper 文件内容
  • 同样的问题。在加载 rails 之前,您需要集合匹配器。将要求移至您 require 'rspec/rails' 之后
猜你喜欢
  • 1970-01-01
  • 2017-12-09
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
相关资源
最近更新 更多