I'm adding Rspec tests to a project that didn't have rspec before, or automated tests at all. It is running on a Windows 7 box. When I run rspec, it shows the error:
undefined method `has_attached_file'
The main issue is that I'm writing just a simple test for a model that is not using Paperclip at all. Paperclip is used on another model.
I've researched extensively, trying to include the gem in test environment but nothing seems to solve the issue.
Is there a way of skipping or forcing the inclussion of paperclip when I run the rspec tests?
My gemfile has, among other things, the following:
source 'http://rubygems.org'
ruby "1.9.2"
gem 'rails', '3.0.20'
...
gem "paperclip", :git => 'git://github.com/thoughtbot/paperclip.git'
gem 'aws-s3'
gem 'aws-sdk'
group :test, :development do
gem 'rspec-rails', '~> 2.14.0'
end
group :test do
gem 'sqlite3'
gem 'capybara', '2.0'
gem 'selenium-webdriver'
gem 'shoulda-matchers'
gem 'database_cleaner'
gem 'launchy', '2.2.0'
gem 'factory_girl_rails'
end
I run the rspec command:
bundle exec rake spec
I get the following error:
C:/Users/MAC/.pik/rubies/Ruby-192-p290/bin/ruby.exe -S rspec ./spec/models/filter_category_spec.rb ./spec/models/filter_spec.rb
C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/attr_encrypted-1.2.1/lib/attr_encrypted.rb:241:in `method_missing': undefined method `has_a
ttached_file' for #<Class:0x5278770> (NoMethodError)
from C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/activerecord-3.0.20/lib/active_record/base.rb:1018:in `method_missing'
from C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/attr_encrypted-1.2.1/lib/attr_encrypted/adapters/active_record.rb:50:in `metho
d_missing_with_attr_encrypted'
....
from C:/Users/MAC/.pik/rubies/Ruby-192-p290/lib/ruby/gems/1.9.1/gems/railties-3.0.20/lib/rails/application.rb:77:in `method_missing'
from C:/Avity/DS Candidates Tracking System/ds-cts/config/environment.rb:5:in `<top (required)>'
from C:/Avity/DS Candidates Tracking System/ds-cts/spec/spec_helper.rb:3:in `require'
from C:/Avity/DS Candidates Tracking System/ds-cts/spec/spec_helper.rb:3:in `<top (required)>'
from C:/Avity/DS Candidates Tracking System/ds-cts/spec/models/filter_category_spec.rb:1:in `require'
My spec_helper file is:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
#Database cleaner
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
#Use chrome driver
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.current_driver = :selenium_chrome
end
Any ideas of what should I do to make this work properly?
EDIT It seems the issue comes before loading spec_helper.rb
If I make changes on this file, like adding errors on purpose, nothing happens and the issue above keeps happening.
The only way I have to run the tests is by commenting the has_attached_file line on my model and adding the group option to the paperclip gem on my Gemfile, to avoid having it on test environment:
gem "paperclip", :git => 'git://github.com/thoughtbot/paperclip.git', :group=>[:development,:production]
Not sure how to solve this without skipping Paperclip from test env.
The problem seems to me to be with shoulda-matchers and paperclip
Add to your spec_helper.rb file
require "paperclip/matchers"
below where you are
require "capybara/rspec"
And add
config.include Paperclip::Shoulda::Matchers
below
RSpec.configure do |config|
Check out the shoulda-matchers documentation for paperclip
Hope this helps
I ran into this issue when trying to use Paperclip in a gem that has ActiveRecord, but not Rails. I was able to fix this for tests by adding a spec/support/paperclip.rb file with the following:
require 'paperclip/railtie'
RSpec.configure do |config|
# Bind paperclip to enable ActiveRecord #has_attached_file method
Paperclip::Railtie.insert
end
As also suggested, this is a good place to add config.include Paperclip::Shoulda::Matchers.
But I'm using Rails 4.2 and Rspec 3, so I think the order of things loaded is much different than yours.
Related
I tried to use shoulda-matchers to test the association between models. However, it always show Error:
TakingTest#test_belongs_to:
NoMethodError: undefined method belong_to' for #<TakingTest:0x00007fc14b8e64a8>
test/models/taking_test.rb:8:inblock in '
I checked other answer, most of them are at least 4 years ago. Does it still work with rails 6.0?
ruby '2.6.5'
rails', '~> 6.0.2'
gem file
group :development, :test do
gem 'rspec-rails'
end
group :test do
gem 'shoulda', '~> 3.5'
gem 'shoulda-matchers'
end
spec/rails_helper.rb:
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
test/models/taking_test.rb
class TakingTest < ActiveSupport::TestCase
test "belongs to" do
should belong_to(:students)
end
end
Having both a spec directory and a test directory could be causing your problem. IMO, there should only ever be spec or test for a every project, never both.
Usually, test files begin with an include for the test_helper.rb file.
require 'test_helper'
Instead of a test_helper, you've got a spec_helper.
Try moving the Shoulda initializer from spec/spec_helper.rb to test/test_helper.rb
I have recently upgraded my ruby on rails project to rails 5.0.7 and ruby 2.5.1 and I am getting an RSPEC error undefined methodexpects' for` different objects I am testing.
I have tried adding a configuration in the spec_helper.rb file as suggested here (although I did a quick search and didn't find :should defined anywhere), here and here:
config.expect_with :rspec do |expectations|
expectations.syntax = [:expect, :expects]
end
Also tried including include RSpec::Matchers in my spec_helper.rb, but then I get even more errors:
`only the `receive`, `have_received` and `receive_messages` matchers are supported with `expect(...).to`, but you have provided: #<RSpec::Matchers::BuiltIn::Eq:0x00007f962b3db058>`
An example of how I am using expect:
describe "process" do
before :each do
#item = Item.new
end
it "parses the uploaded file and extract the correct report data" do
item_a_data = {"name" => "one"}
item_b_data = {"name" => "two"}
file_contents = {"items" => [item_a_data, item_b_data]}
#item.data_file = double("file", :read => file_contents.to_json)
#item.name = item_a_data["name"]
#item.expects(:interpret_json_file).with(#item.data_file).returns(file_contents)
#item.expects(:save).returns(true)
expect(#item.process_data_file).to be_truthy
expect(#item.data).to eq item_a_data.to_json
end
Notice that the error occurs when I call #item.expects
In my Gemfile I have the following gems (among others):
group :development, :test do
gem 'byebug'
gem 'sqlite3'
gem 'rspec-rails'
gem 'rb-fsevent', '~> 0.9.1'
gem 'guard-rspec', '4.7.3'
gem 'guard-spork', '2.1.0'
gem 'spork', '0.9.2'
gem 'jasmine-rails'
gem 'teaspoon-jasmine'
end
group :test do
gem 'capybara'
gem 'cucumber-rails', :require => false
gem 'database_cleaner'
gem 'factory_girl_rails', '4.1.0'
gem 'launchy'
gem 'poltergeist'
gem 'timecop'
gem 'webmock'
gem 'simplecov', '~> 0.16.0'
gem 'rails-controller-testing'
end
spec_helper.rb:
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
Spork.prefork do
require 'simplecov'
SimpleCov.start 'rails'
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'devise'
require './spec/controllers/controller_helpers.rb'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.include Devise::Test::ControllerHelpers, type: :controller
config.include ControllerHelpers, type: :controller
config.include Capybara::DSL
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
config.infer_spec_type_from_file_location!
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
config.include FactoryGirl::Syntax::Methods
# config.expect_with :rspec do |expectations|
# expectations.syntax = :expect
# end
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
The solution would be to re-write it to the following syntax:
expect(#item).to receive(:interpret_json_file).with(#item.data_file) { file_contents }
expect(#item).to receive(:save) { true }
Basically ActiveRecord model does not know about rspec expectations and it should not. If that specs were working before then you might used some decoration for ActiveRecord models and that is why it worked previously.
In gem file I write this:
group :test do
gem 'rspec-rails'
gem 'shoulda-matchers', require: false
gem 'factory_girl'
end
My rails_helper
require 'rspec/rails'
require 'shoulda/matchers'
My spec_helper
require 'rails_helper'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.include FactoryGirl::Syntax::Methods
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
Shoulda::Matchers.configure do |config|
config.integrate do |with|
# Choose a test framework:
with.test_framework :rspec
# Choose one or more libraries:
with.library :active_record
with.library :active_model
with.library :action_controller
end
end
And finally my test:
require 'spec_helper'
describe Person do
it {should validate_presence_of(:identifier)}
end
And I get nomethoderror
Failure/Error: it {should validate_presence_of(:identifier)}
NoMethodError:
undefined method `validate_presence_of' for #<RSpec::ExampleGroups::Person:0x007fe58d13ca20>
I simply don't get it. In other project the same way works. Here it doesn't. I have spent two days to fix this problem. Are there better alternatives of Shoulda Matchers in rails?
Sorry you're having trouble. You need to load Rails before you require shoulda-matchers. The gem will only make model matchers available if it can see that ActiveRecord is available; if not, then you won't get them.
It appears that you have rails_helper and spec_helper swapped. Typically in a fresh project with rspec-rails installed, rails_helper will load Rails and then require spec_helper. I would remove both files (or move them aside so you still have them) and then re-run rails g rspec:install to regenerate them. You'll still want to add the shoulda-matchers configuration block to rails_helper as you have done, but by that point ActiveRecord (and the rest of Rails) should be loaded.
Change your Gemfile to use two different groups for test like this:
group :test, :development do
gem 'rspec-rails'
gem 'factory_girl'
end
group :test do
gem 'shoulda-matchers', require: false
end
This used to be caused when shoulda would load with Test::Unit instead of RSpec, but I thought that was fixed.
I tried to test my project. It was working before and I don't know what i did to whenever i type bundle exec rspec spec/ it says cannot load such file -- capybara/rspec (LoadError). And Please I need an advice to which one is good for testing my MVC in ruby on rails as a newbie.
Gemfile:
------------
group :test do
# Pretty printed test output
gem 'turn', :require => false
gem 'minitest'
gem 'capybara', '1.1.2'
gem 'rb-inotify', '0.8.8'
gem 'libnotify', '0.5.9'
gem 'guard-spork', '0.3.2'
gem 'spork', '0.9.0'
gem 'spork-testunit'
gem 'guard-test'
gem 'ruby-prof'
gem 'factory_girl_rails', '1.4.0'
if RUBY_PLATFORM =~ /linux/
gem 'capybara-webkit'
end
gem 'launchy'
end
group :development, :test do
gem 'rspec-rails', '2.10.0'
gem 'guard-rspec', '0.5.5'
end
spec_helper:
require 'rubygems'
#require 'factory_girl'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
require 'capybara/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
#Capybara.default_driver = :selenium
Capybara.javascript_driver = :webkit
end
Error:
/home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/dependencies.rb:251:in `require': cannot load such file -- capybara/rspec (LoadError)
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/dependencies.rb:251:in `block in require'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/dependencies.rb:236:in `load_dependency'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/activesupport-3.2.9/lib/active_support/dependencies.rb:251:in `require'
from /home/IN4SYSTEMS/sri.kalai/Documents/promaster/spec/spec_helper.rb:11:in `<top (required)>'
from /home/IN4SYSTEMS/sri.kalai/Documents/promaster/spec/helpers/loc/epcs_helper_spec.rb:1:in `require'
from /home/IN4SYSTEMS/sri.kalai/Documents/promaster/spec/helpers/loc/epcs_helper_spec.rb:1:in `<top (required)>'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/configuration.rb:746:in `load'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/configuration.rb:746:in `block in load_spec_files'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/configuration.rb:746:in `map'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/configuration.rb:746:in `load_spec_files'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/command_line.rb:22:in `run'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/runner.rb:66:in `rescue in run'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/runner.rb:62:in `run'
from /home/IN4SYSTEMS/sri.kalai/Desktop/gems/ruby/1.9.1/gems/rspec-core-2.10.1/lib/rspec/core/runner.rb:10:in `block in autorun'
Thanks in advance!!!
I hope you did install all required gems? Using bundle install BTW did you change Gemfile, in that case you would be required to install Gems using bundle install.
You could check list of gems available by gem list
Regarding second part of the question, which testing API to use. It is matter of choice. You could stick with rpsec and if you find it falls short of your expectation, then look out for change.
Try gem query --local to see if capybara-screenshot appears in your list of installed gems. (For some reason, this rendered a different list than gem list for me.)
If you don't see it, then try gem install capybara-screenshot. It is not included in the installation of capybara, so seeing capybara in your list of gems alone is not sufficient!
I had the same problem today and I fixed it in the following way:
Comment in file spec_helper.rb
next raws
require 'capybara/rspec'
require 'capybara/rails',
Remove
/usr/local/rvm/gems/ruby-1.9.3-p327#olha/gems/capybara-webkit-1.1.0
from my HDD space.
I'm getting the following error when I try to run an rspec test:
/srv/offerme/spec/requests/static_pages_spec.rb:13: undefined method `visit' for #<Class:0xb3436684> (NoMethodError)
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:238:in `module_eval'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:238:in `subclass'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:224:in `describe'
from /srv/offerme/spec/requests/static_pages_spec.rb:12
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:238:in `module_eval'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:238:in `subclass'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:224:in `describe'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/dsl.rb:18:in `describe'
from /srv/offerme/spec/requests/static_pages_spec.rb:3
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load_spec_files'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `map'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load_spec_files'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:22:in `run'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:69:in `run'
from /var/lib/gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:8:in `autorun'
from /usr/local/bin/rspec:19
The file I get this error in looks like this (spec/requests/static_pages_spec.rb) :
require 'spec_helper'
describe "StaticPages" do
include Capybara::DSL
describe "GET /static_pages" do
it "works! (now write some real specs)" do
# Run the generator again with the --webrat flag if you want to use webrat methods/matchers
get static_pages_index_path
response.status.should be(200)
end
end
describe "Home page" do
visit 'static_pages/home'
page.should have_content('OfferMe')
end
end
My spec_helper.rb file looks like this:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
config.include Capybara::DSL
end
module ::RSpec::Core
class ExampleGroup
include Capybara::DSL
include Capybara::RSpecMatchers
end
end
And, finally, my Gemfile looks like this:
source 'https://rubygems.org'
gem 'rails', '3.2.7'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
group :development, :test do
gem 'sqlite3'
gem 'rspec-rails'
end
group :test do
gem 'capybara'
end
gem 'json'
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sass-rails', '~> 3.2.4'
gem 'coffee-rails', '~> 3.2.2'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
gem 'twitter-bootstrap-rails'
end
gem 'jquery-rails'
# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'
# To use Jbuilder templates for JSON
# gem 'jbuilder'
# Use unicorn as the app server
# gem 'unicorn'
# Deploy with Capistrano
# gem 'capistrano'
# To use debugger
# gem 'ruby-debug'
gem 'therubyracer', '0.10.1'
gem 'libv8'
gem 'webrat'
I have seen this GitHub issue and have tried some of the workarounds as well as looked at some other StackOverflow questions pertaining to the similar issue (that's why some of the code looks redundant/hacky). However, none of them have worked yet. Please help!
UPDATE:
The problem is that you're calling visit outside of an it block, here:
describe "Home page" do
visit 'static_pages/home'
page.should have_content('OfferMe')
end
Wrap those middle lines in an it block:
describe "Home page" do
it "has a homepage" do
visit 'static_pages/home'
page.should have_content('OfferMe')
end
end
That should work.
ORIGINAL ANSWER:
I could be wrong, but I believe you have to include capybara in both the test and development sections of your Gemfile.
Try changing that section of your Gemfile to this:
group :development, :test do
gem 'sqlite3'
gem 'rspec-rails'
gem 'capybara'
end
This is an old post. I have had the same issue. I thought I share my solution.
In my Gemfile I have had
group :test do
gem 'capybara'
end
And the visit was in the right spot however I was getting the same error. so this is what I did. I ran the update on the Gem and all are good now.
bundle update capybara
Hope this help someone.