RSpec undefined method "errors_on" - ruby-on-rails

I have the following model that I want to test with RSpec:
class Language < ActiveRecord::Base
has_and_belongs_to_many :dvds
validates :title, presence: true, uniqueness: { case_sensitive: false }
end
language_spec.rb
describe Language do
describe 'title validation' do
context 'title is present' do
before(:each) do
#lang = Language.new(title: 'English')
end
it 'is valid with present title' do
expect(#lang).to have_exactly(0).errors_on(:title)
end
end
context 'title is not present' do
before(:each) do
#lang = Language.create
end
it 'has an error on title attribute' do
expect(#lang).to have_exactly(1).errors_on(:title)
end
end
end
end
Unfortunately I'm getting test failures:
Failures:
1) Language title validation title is present is valid with present
title
Failure/Error: expect(#lang).to have_exactly(0).errors_on(:title)
NoMethodError:
undefined method errors_on' for #<Language:0xaa40e98>
# ./spec/models/language_spec.rb:9:inblock (4 levels) in '
2) Language title validation title is not present has an error on
title attribute
Failure/Error: expect(#lang).to have_exactly(1).errors_on(:title)
NoMethodError:
undefined method errors_on' for #<Language id: nil, title: nil, created_at: nil, updated_at: nil>
# ./spec/models/language_spec.rb:19:inblock (4 levels) in '
Gemfile
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.1.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.3'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring', group: :development
# Pagination plugin
gem 'will_paginate', '~> 3.0'
# Testing
group :development, :test do
gem "rspec-rails", "~> 3.0.1"
gem "factory_girl_rails", "~> 4.4.1"
end
group :test do
gem "faker", "~> 1.3.0"
gem "capybara", "~> 2.3.0"
gem "database_cleaner", "~> 1.3.0"
gem "launchy", "~> 2.4.2"
gem "selenium-webdriver", "~> 2.42.0"
end
Any ideas why I'm getting undefined method "errors_on"?

The errors_on matcher moved to the rspec-collection_matchers gem, so adding that to your Gemfile would fix the error.
If you wanted to move away from non-core syntax, you could do
describe Language do
describe 'title validation' do
context 'title is present' do
before(:each) do
#lang = Language.new(title: 'English')
end
it 'is valid with present title' do
expect(#lang.errors[:title]).to be_empty
end
end
context 'title is not present' do
before(:each) do
#lang = Language.create
end
it 'has an error on title attribute' do
expect(#lang.errors.added?(:title, :blank)).to be_true
end
end
end
end
(have_exactly and related matchers have also moved to rspec-collection_matchers.)

Try to set type option:
describe Language, type: :model do
Or use infer_spec_type_from_file_location! (See here)
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end

Related

rspec-rails+capybara NoMethodError:undefined method `create'

I'm learning ruby on rails, but I have a problem that I couldn't solve by myself. Any one can help me?
when I run:bundle exec rspec spec/models/user_spec.rb, I got this error:
Failure/Error: #user = create(:user) NoMethodError:
undefined method `create' for #<RSpec::ExampleGroups::User::PropertiesShouldNotNil:0xb807450>
# ./spec/models/user_spec.rb:6:in `block (3 levels) in <top (required)>'
Gemfile:
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '5.0.0.rc2'
# Use mysql as the database for Active Record
gem 'mysql2'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails', '~> 2.3.0'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'alipay', '~> 0.10.0' #支付宝接口
gem 'capistrano-rails', :group => :development
gem 'capistrano-passenger', :group => :development
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'
# Access an IRB console on exception pages or by using <%= console %> in views
#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 'rspec-rails'
gem "capybara"
end
group :development do
gem 'web-console', group: :development
end
spec/rails_helper.rb:
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rails'
require 'capybara/rspec'
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!
end
app/models/user.rb
app/models/user.rb
has_many :recipients
end
spec/models/user_spec.rb:
require 'rails_helper'
RSpec.describe User, type: :model do
context "properties should not nil" do
before do
#user = create(:user)
end
subject{ #user }
it { should respond_to(:name) }
it { should respond_to(:passwd) }
end
end
This error is because the create method you are trying to call is usually defined in the FactoryGirl class. FactoryGirl is a Ruby gem that lets you define custom factories to instantiate your application-specific models.
As you may need to integrate this gem in your Rails app, I suggest that you use the factory_girl_rails gem. Simply add the gem declaration into the :test group of your Gemfile, like as follows:
group :development, :test do
# Here go other gem declarations...
gem 'factory_girl_rails'
end
Once you have included this gem in your project, you'll need to define the factories for your models (in this case, your User model) in order to specify the way you want your test instances to be built or created. I recommend you read this basic documentation on how to define factories with FactoryGirl (I read this doc over and over).
In advance, I could tell you that the factories are usually defined under the spec/factories folder (in cases like this, that you are using RSpec) and have a common structure. In this case, your Userfactory would be defined in a file like spec/factories/user.rb and be like:
FactoryGirl.define do
factory :user do
# Here you assign values to the different attributes, like:
# username "username"
# password "pass"
# ...
end
end
I use the faker gem with FactoryGirl a lot, because it lets me create random values for names, telephone numbers, emails, etc in a way that are always different but make sense. Take a look at its documentation in case you are interested in it.
Hope these can help you solve your problem!

undefined method `authenticate' on Devise + Rspec + render_view

I have Rails 4.2.5 and rspec 3.4.1
When I add render_views some first controllers test are failed.
I use render_views because I don't know any methods to watch what happens on a page.
Gemfile
source 'https://rubygems.org'
gem 'rails', '4.2.5'
gem 'sqlite3'
gem 'haml-rails', '~> 0.9'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'twitter-bootstrap-rails'
gem 'less-rails'
gem 'therubyracer', platforms: :ruby
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc
group :development, :test do
gem 'rspec-rails', '~> 3.0'
gem 'cucumber-rails', :require => false
gem 'database_cleaner'
gem 'factory_girl_rails'
gem 'shoulda-matchers'
gem 'capybara'
gem 'capybara-screenshot'
gem 'byebug'
end
group :development do
gem 'web-console', '~> 2.0'
gem 'spring'
end
gem 'devise'
gem 'cancan'
gem "role_model"
gem 'paperclip', '~> 4.3'
gem 'jquery-fileupload-rails'
gem 'stringex'
gem 'will_paginate'
gem 'russian', '~> 0.6.0'
spec/controllers/users_controller_spec.rb
RSpec.describe UsersController, type: :controller do
render_views
let(:valid_attributes) {
{email: "admin#example.com",
password: "password",
password_confirmation: "password"}
}
let(:invalid_attributes) {
}
let(:valid_session) { {} }
describe "GET #index" do
it "says 'Users'" do
get :index
end
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 'devise'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
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
rspec spec/controllers/page_controller_spec.rb
PageController
GET #index
returns http success (FAILED - 1)
Failures:
1) PageController GET #index returns http success
Failure/Error: - if user_signed_in?
ActionView::Template::Error:
undefined method `authenticate' for nil:NilClass
# /home/ilp/.rvm/gems/ruby-2.1.4/gems/devise-3.5.3/lib/devise/controllers/helpers.rb:124:in `current_user'
# /home/ilp/.rvm/gems/ruby-2.1.4/gems/devise-3.5.3/lib/devise/controllers/helpers.rb:120:in `user_signed_in?'
# ./app/views/layouts/main.html.haml:36:in `_app_views_layouts_main_html_haml___2814915178728912122_59040000'
# ./spec/controllers/page_controller_spec.rb:11:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# NoMethodError:
# undefined method `authenticate' for nil:NilClass
# /home/ilp/.rvm/gems/ruby-2.1.4/gems/devise-3.5.3/lib/devise/controllers/helpers.rb:124:in `current_user'
Finished in 0.26407 seconds (files took 1.9 seconds to load)
1 example, 1 failure
app/controllers/page_controller.rb
class PageController < ApplicationController
def index
end
end
If I call sign_in or sign_our methods tests are success.
You need to call the sign_in method before rendering as it check the current_user object and calls the authenticate! method on current_user object which is nil so throwing error!
Do it like this
before do
sign_in_user
end
this will set the current_user object.

Why am I getting an error while using RSpec 3.0 with Capybara 2.3 in Rails 4.1?

I am new to Rails development. I am following Michael Hartl's video tutorials. However I am not able to run the tests using Capybara/RSpec. I am getting some errors. My setup is as follows:
I am using Ruby 2.0.0p353.
Rails - 4.1.1 and
RSpec - 3.0.1
Capybara - 2.3.0
Below is my GemFile.
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
ruby '2.0.0'
gem 'rails', '4.1.1'
gem 'bootstrap-sass'
gem 'bcrypt'
gem 'faker'
gem 'will_paginate'
gem 'bootstrap-will_paginate'
gem 'rails_12factor'
# Use sqlite3 as the database for Active Record
group :development, :test do
gem 'sqlite3'
gem 'rspec-rails'
gem 'guard-rspec'
gem 'guard-spork'
gem 'childprocess'
gem 'spork'
end
#Gems used only for assets and not used in production enviornment by default
group :assets do
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.3'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
end
group :test do
gem 'capybara'
gem 'factory_girl_rails'
gem 'cucumber-rails'
gem 'database_cleaner'
#gem 'launchy'
#gem 'rb-fsevent'
#gem 'growl'
end
group :production do
gem 'pg'
end
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring', group: :development
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
# Use debugger
# gem 'debugger', group: [:development, :test]
Below is my spec/spec_helper.rb:
require 'capybara/rspec'
RSpec.configure do |config|
config.include Capybara::DSL
end
And, here is my spec. test - spec/features/static_pages_spec.rb
require 'spec_helper'
describe "Static pages" do
describe "Home page" do
it "should have the content 'Sample App'" do
visit '/static_pages/home'
page.should have_content('Sample App')
end
end
end
If I run the command rspec/featues/static_pages_spec.rb I get a long stack trace. It shows two main issues:
/usr/local/share/ruby/site_ruby/rubygems/core_ext/kernel_require.rb:73:
warning: loading in progress, **circular require considered harmful -
/home/MAC/.gem/ruby/gems/capybara-2.3.0/lib/capybara.rb**
and
An error occurred in an after hook
**ArgumentError: rack-test requires a rack application, but none was given**
occurred at /home/MAC/.gem/ruby/gems/capybara-2.3.0/lib/capybara/rack_test/driver.rb:16:in `initialize'
F
Failures:
1) Static pages Home page should have the content 'Sample App'
Failure/Error: visit '/static_pages/home'
ArgumentError:
**rack-test requires a rack application, but none was given**
# ./spec/features/static_pages_spec.rb:10:in `block (3 levels) in <top (required)>'
Finished in 0.00062 seconds (files took 0.58874 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/features/static_pages_spec.rb:8 # Static pages Home page should have the content 'Sample App'
I have tried googling for this issue. It seems Capybara 2.3.0 and RSpec 3.0.1 do not play nicely. However I haven't found any solution which solves the issue. Has anyone encountered and solved such an issue? Please let me know. Thanks in advance.
rspec-rails 3 no longer defaults to setting the spec type based on the location, so your spec isn't being setup as a feature spec
You can either tag the feature specs individually or add
config.infer_spec_type_from_file_location!
To your spec helper to restore the old behaviour

Rspec + Capybara: controller missing, integration spec passes anyway

I started a fresh new rails app (using rspec-rails 2.99 & capybara 2.3.0), and wrote a silly simple integration spec to get started with TDD:
# spec/integration/visit_home_page_spec.rb
require 'spec_helper'
feature "view the home page" do
scenario "user visits home page" do
visit root_path
expect(page).to have_content 'Password'
end
end
As expected, the test fails due to root_path being undefined - so I went ahead and:
# config/routes.rb
root 'users#new'
And here's the problem: instead of the spec failing due to UsersController being undefined, it's green. It appears that rspec is evaluating the error page itself, and since that page happens to contain the word "password", the spec passes.
To make sure that's what's happening, I have modified the spec to:
# spec/integration/visit_home_page_spec.rb
...
expect(page).to have_content 'theresnowaythisisinthepage'
...
Now the test fails, but not because it's picking up the undefined UsersController - just because the content is not in the error page.
I've started many an app with this approach, and it's the first time I've seen rspec mistaking an error page for a valid one - what did I break?
I suspect my forehead will have a big hand-shaped mark when I find the answer.
--
Here's my Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 4.1.1'
gem 'mysql2', '~> 0.3.16'
gem 'sass-rails', '~> 4.0.2'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'active_model_serializers', '~> 0.8.1'
gem 'slim-rails', '~> 2.1.4'
gem 'bootstrap-sass', '~> 3.1.1.1'
gem 'bootstrap-generators', '~> 3.1.1.3'
group :test, :development do
gem 'rspec-rails', '~> 2.99'
gem 'capybara', '~> 2.3.0'
end
group :development do
gem "better_errors"
gem "binding_of_caller" # required by better-errors
gem "launchy"
end
group :doc do
gem 'sdoc', require: false
end
Here's 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.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.infer_spec_type_from_file_location!
config.include Capybara::DSL
end

Ruby on Rails 4 and RSPEC

I am trying to get to grips with Rails and Rspec for testing using Capybara. I’m currently trying to test for uniqueness of a Profile Name for User. However from reading around fixtures should not be used with Rspec. How do I go about adding some base data for me to test against.
Gemfile
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.3'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'
gem 'devise', '~> 3.2.3'
gem 'simple_form', '~> 3.0.1'
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
group :development do
gem 'awesome_print'
end
group :development, :test do
gem 'rspec-rails', '~> 2.0'
end
group :test do
gem 'capybara', '~> 2.0'
end
# Use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.1.2'
# Use unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano', group: :development
# Use debugger
# gem 'debugger', group: [:development, :test]
Create_spec.rb
require 'spec_helper'
describe "Creating a new user" do
def create_user(options={})
options[:first_name] ||= "Adam"
options[:last_name] ||= "Sackfield"
options[:profile_name] ||= "Sacki"
options[:email] ||= "email#email.com"
options[:password] ||= "password"
visit "/users/sign_up"
expect(page).to have_content "Sign up"
fill_in "First name", with: options[:first_name]
fill_in "Last name", with: options[:last_name]
fill_in "Profile name", with: options[:profile_name]
fill_in "Email", with: options[:email]
fill_in "Password", with: options[:password]
fill_in "Password confirmation", with: options[:password]
click_button "Sign up"
end
it "a user can register" do
create_user
expect(page).to have_content "You have signed up"
end
it "a user must enter a first name" do
create_user first_name: ""
expect(page).to_not have_content "You have signed up"
end
it "a user must enter a last name" do
create_user last_name: ""
expect(page).to_not have_content "You have signed up"
end
end
Thanks
Use factory_girl_rails gem.
factory_girl_rails provides Rails integration for factory_girl
which is a fixtures replacement with a straightforward definition
syntax, support for multiple build strategies (saved instances,
unsaved instances, attribute hashes, and stubbed objects), and support
for multiple factories for the same class (user, admin_user, and so
on), including factory inheritance.
Create a folder under spec directory as factories.
In spec_helper.rb,
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods ## Add only this line
end
Create factory files under spec/factories directory and define the required factories
as shown in Factory Girl Documentation
In your spec files, use the defined factories as shown here

Resources