undefined method `authenticate' on Devise + Rspec + render_view - ruby-on-rails

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.

Related

Setting up factory girl in Rails 5. Docs seem to leave out an important step

What am I doing wrong? It seems like nowhere in the docs does it say to put:
require 'factory_girl_rails'
require 'support/factory_girl'
in your rails_helper.
This is my setup without the two lines:
Gemfile:
source 'https://rubygems.org'
gem 'rails', '>= 5.0.0.beta3', '< 5.1'
gem 'sqlite3'
gem 'puma'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'turbolinks', '~> 5.x'
gem 'jbuilder', '~> 2.0'
gem 'carrierwave'
gem 'carrierwave_direct'
gem "mini_magick"
group :development, :test do
gem 'pry'
gem 'rspec-rails', '~> 3.0'
gem 'factory_girl_rails'
gem 'database_cleaner', '~> 1.5', '>= 1.5.1'
end
group :development do
gem 'web-console', '~> 3.0'
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
User model:
class User < ApplicationRecord
has_many :images
end
Factories.rb file inside spec:
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "jeff#{n}" }
after(:build) do |user, eval|
user.images << build(:image)
end
end
factory :image do
avatar File.open(File.join(Rails.root, '/spec/support/images/blueapron.jpg'))
end
end
This is my spec/models/user_spec.rb:
describe User do
before(:each) do
#user = create(:user)
end
describe "images" do
it "should have multiple images" do
require 'pry' ; binding.pry
#user.images.create({document_file:File.open(File.join(Rails.root, '/spec/fixtures/files/image.png'))})
#user.images.create({document_file:File.open(File.join(Rails.root, '/spec/fixtures/files/image.png'))})
#user.images.length.should eq(3)
end
end
end
When I run my tests:
Failures:
1) User images should have multiple images
Failure/Error: #user = create(:user)
NoMethodError:
undefined method `create' for #<RSpec::ExampleGroups::User::Images:0x007fea80756f08>
# ./spec/models/user_spec.rb:4:in `block (2 levels) in <top (required)>'
AFter I include those two lines back into my rails_helper:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'factory_girl_rails'
require 'support/factory_girl'
All of a sudden it works now:
before(:each) do
4: #user = create(:user)
5: end
6: describe "images" do
7: it "should have multiple images" do
=> 8: require 'pry' ; binding.pry
9:
10: #user.images.create({document_file:File.open(File.join(Rails.root, '/spec/fixtures/files/image.png'))})
11: #user.images.create({document_file:File.open(File.join(Rails.root, '/spec/fixtures/files/image.png'))})
12:
13: #user.images.length.should eq(3)
[1] pry(#<RSpec::ExampleGroups::User::Images>)> #user
=> #<User:0x007f86e86cbcd8 id: 1, name: "jeff2", created_at: Thu, 17 Mar 2016 04:39:42 UTC +00:00, updated_at: Thu, 17 Mar 2016 04:39:42 UTC +00:00>
I don't even remember where I found those two lines. Is it in the docs anywhere to include those lines?
In your factory, you use build:
after(:build) do |user, eval|
user.images << build(:image)
end
And in your specs you use create:
describe User do
before(:each) do
#user = create(:user)
end
You have to use same hook, I recommend you to:
Use build instead of create and save record in your before(:each) block
Include another hook for after(:create) in your factory and create (not build) an image

uninitialized constant TestFactories (NameError)

I am a beginner in Ruby on Rails and I am writing a "User sign in" spec for a wiki project, and I am getting the following error:
uninitialized constant TestFactories (NameError)
This is my sign_in_spec.rb
require 'rails_helper'
describe "Sign in flow" do
include TestFactories
before do
#user = authenticated_user
end
describe "successful" do
it "redirects user to the wikis index" do
user = authenticated_user
visit root_path
end
end
end
This is my test_factories.rb file:
module TestFactories
def authenticated_user(options={})
user_options = { email: "email#{rand}#fake.com", password: 'password' }.merge(options)
user = User.new(user_options)
user.skip_confirmation!
user.save
user
end
end
This is my Gemfile:
source 'https://rubygems.org'
gem 'rails'
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'bootstrap-sass', '~> 3.2.0'
gem 'autoprefixer-rails'
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
# Testing
group :develpment, :test do
gem 'rspec-rails'
gem 'capybara'
gem 'database_cleaner'
gem 'factory_girl_rails', '~> 4.0'
gem 'pry-rails'
end
# Databases
# Developemnt
gem 'sqlite3'
or you can do something like this in sepc helper
RSpec.configure do |config|
config.include TestFactories
end

RSpec undefined method "errors_on"

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

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

undefined method `visit' for #<RSpec

i'm sure this is answered somewhere on stackoverflow but for the life of me, i can't find why my situation is different than what is already written so here goes.
using rspec w/ capybara
1) report_cards#index must have 'Report Cards Index'
Failure/Error: visit '/'
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_4:0x007fcc3aa33960>
# ./spec/views/report_cards_view_spec.rb:7:in `block (2 levels) in <top (required)>'
/spec/views/report_cards_view_spec.rb looks like
require 'spec_helper'
describe "report_cards#index" do
it "must have 'Report Cards Index'" do
visit '/'
page.should have_content("something")
end
end
top lines from spec_helper.rb looks like
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'capybara/rspec'
gemfile looks like
`source 'https://rubygems.org'`
gem 'rails', '3.2.7'
gem 'jquery-rails'
gem 'pg', '~> 0.14.0'
gem 'devise', '~> 2.1.2'
gem "quiet_assets", "~> 1.0.1"
gem 'thin'
gem 'bourbon'
gem "haml-rails"
gem "httparty", "~> 0.8.3"
gem "activerecord-import", "~> 0.2.10"
group :test, :development do
gem "rspec-rails", "~> 2.0"
gem 'capybara', '~>1.1.2'
gem "fabrication", "~> 2.2.0"
gem "launchy", "~> 2.1.2"
end
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'uglifier', '>= 1.0.3'
end`
i'm pretty junior so go easy :) - THX !
capybara is not included in views spec, and it is for integration testing.
try to move your spec file into spec/requests directory
I had a similar issue and all i had to do was to add
config.include Capybara::DSL
to the spec_helper.rb file

Resources