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 method
expects' 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.