What error is AttributeDoesNotExistError in Should Matcher...?

Asked 1 years ago, Updated 1 years ago, 96 views

I'm writing a model spec using rspec, factory-girl, and shoulda-matcher.

Using validate_presence_of provided by shoulda-matcher, we are writing a spec that an empty or false cannot be entered in the field.

AttributeDoesNotExistError is displayed..

Maybe I set up the shoulder or installed it wrong, but I didn't know which part to look at...

Gemfile

source 'https://rubygems.org'
ruby '2.3.0'


# # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.6'
# # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'

# # Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'
gem 'pry'
gem 'pg', '~> 0.18.4'
gem 'figaro', '~> 1.1.1'
gem 'pry-rails'

# # Use Unicorn as the app server
# # gem 'unicorn'

# # Use Capistrano for deployment
# # gem 'capistrano-rails', group: :development

group :test do
  gem 'database_cleaner', '~> 1.5.1'
  gem 'shoulda-matchers', '~> 3.1.1'
end

group :development, :test do
  # # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'
  gem 'rspec-rails', '~> 3.4.2'
  gem 'guard', '~> 2.13.0'
  gem 'guard-rspec', '~> 4.6.5'
  gem 'factory_girl_rails', '~> 4.7.0'
  gem 'faker', '~> 1.6.3'
end

group :development do
  gem 'web-console', '~> 2.0'

  # # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'annotate'
end

spec/spec_helper.rb

require 'database_cleaner'

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
    expectations.syntax = :expect
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
end

spec/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'
require 'shoulda/matchers'

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

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!
end

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

spec/factories/content.rb

# == Schema Information
#
# # Table name: contents
#
#  #  id         :integer          not null, primary key
#  #  txt        :text
#  #  created_at :datetime         not null
#  #  updated_at :datetime         not null
#

FactoryGirl.define do
  factory :content do
    txt { Faker::Lorem.paragraph }
  end
end

app/model/content.rb

# == Schema Information
#
# # Table name: contents
#
#  #  id         :integer          not null, primary key
#  #  txt        :text
#  #  created_at :datetime         not null
#  #  updated_at :datetime         not null
#

class Content < ActiveRecord::Base
  validates :txt, presence: true
end

Content models are created successfully.

$ rails c
Running via Spring preloader in process 8237
Loading development environment (Rails 4.2.6)
[1] [1] pry(main)> Content.create(txt: Faker::Lorem.paragraph)
   (0.2ms)  BEGIN
  SQL (2.1ms)  INSERT INTO "contents" ("txt", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["txt", "Amet temporibus nobis deserunt adipisci. Eligendi eveniet quo cumque voluptas ut quibusdam autem. Recusandae tempore consectetur qui veniam est hic voluptatem. Aliquam maxime et accusantium nostrum ad. Earum molestiae amet modi cupiditate id ut et."], ["created_at", "2016-04-11 02:08:09.637109"], ["updated_at", "2016-04-11 02:08:09.637109"]]
   (6.3ms)  COMMIT
=> #<Content:0x007fb828712d60
 id: 1,
 txt:
  "Amet temporibus nobis deserunt adipisci. Eligendi eveniet quo cumque voluptas ut quibusdam autem. Recusandae tempore consectetur qui veniam est hic voluptatem. Aliquam maxime et accusantium nostrum ad. Earum molestiae amet modi cupiditate id ut et.",
 created_at: Mon, 11 Apr 2016 11:08:09 KST +09:00,
 updated_at: Mon, 11 Apr 2016 11:08:09 KST +09:00>
[2] [2] pry(main)> Content.last
  Content Load (0.4ms)  SELECT  "contents".* FROM "contents"  ORDER BY "contents"."id" DESC LIMIT 1
=> #<Content:0x007fb822044700
 id: 1,
 txt:
  "Amet temporibus nobis deserunt adipisci. Eligendi eveniet quo cumque voluptas ut quibusdam autem. Recusandae tempore consectetur qui veniam est hic voluptatem. Aliquam maxime et accusantium nostrum ad. Earum molestiae amet modi cupiditate id ut et.",
 created_at: Mon, 11 Apr 2016 11:08:09 KST +09:00,
 updated_at: Mon, 11 Apr 2016 11:08:09 KST +09:00>
[3] [3] pry(main)>

spec/models/content_spec.rb

# == Schema Information
#
# # Table name: contents
#
#  #  id         :integer          not null, primary key
#  #  txt        :text
#  #  created_at :datetime         not null
#  #  updated_at :datetime         not null
#

require 'rails_helper'

describe Content do
  let(:content) { create(:content) }
  it 'is valid' do
    expect(build(:content)).to be_valid
  end

  it { expect(:content).to validate_length_of(:txt).is_at_least(100) }
end

Run rspec

$ bundle exec rspec
.F

Failures:

  1) 1) Content should validate that :txt cannot be empty/falsy
     Failure/Error: it { expect(:content).to validate_presence_of :txt }

     Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeDoesNotExistError:
       The matcher attempted to set :txt on the Symbol to nil, but that
       attribute does not exist.
     # # ./spec/models/content_spec.rb:19:in `block (2 levels) in <top (required)>'

Finished in 0.29974 seconds (files took 1.49 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/models/content_spec.rb:19 # Content should validate that :txt cannot be empty/falsy

$

I don't know what the problem is. ㅠ<

ruby-on-rails ruby shoulda-matcher rspec ruby-on-rails-4

2022-09-22 21:44

1 Answers

Problem

it { expect(:content).to validate_length_of(:txt).is_at_least(100) }

I think it's because it passed the :content symbol to aspect.

Solution

it { expect(content).to validate_length_of(:txt).is_at_least(100) }

Enter the content variable defined by let as above, or

it { should validate_length_of(:txt).is_at_least(100) }

or

it { is_expected.to validate_length_of(:txt).is_at_least(100) }

Like this, you can use the short and method provided by shoulda-matchers.


2022-09-22 21:44

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.