Rspec failing when attempting to find user in DB - ruby-on-rails

I can't figure out what I'm doing wrong in my model spec (user_spec.rb). I'm attempting to check that the authentication method works with a valid password, but something is going wrong in the User.find_by part of the spec I think since it returns nil. I've checked that it responds to :authenticate, :password, and :password_confirmation, which passes (I'll omit that in the code below for the sake of readability).
Here's the failure I'm getting when running the spec:
Failures:
1) User return value of authenticate method with valid password should eq #<User id: 136, fullname: "Sherwood Hickle", email: "jewell.brekke#stokes.net", created_at: "2013-11-06 23:04:35", updated_at: "2013-11-06 23:04:35", password_digest: "$2a$04$O5V2X9sZrl/u2T9W25c3Pu/PU6XaIvtZSIB39Efkid6a...">
Failure/Error: it { should eq found_user.authenticate(user.password) }
expected: #<User id: 136, fullname: "Sherwood Hickle", email: "jewell.brekke#stokes.net", created_at: "2013-11-06 23:04:35", updated_at: "2013-11-06 23:04:35", password_digest: "$2a$04$O5V2X9sZrl/u2T9W25c3Pu/PU6XaIvtZSIB39Efkid6a...">
got: #<User id: nil, fullname: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil>
(compared using ==)
Diff:
## -1,2 +1,2 ##
-#<User id: 136, fullname: "Sherwood Hickle", email: "jewell.brekke#stokes.net", created_at: "2013-11-06 23:04:35", updated_at: "2013-11-06 23:04:35", password_digest: "$2a$04$O5V2X9sZrl/u2T9W25c3Pu/PU6XaIvtZSIB39Efkid6a...">
+#<User id: nil, fullname: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil>
# ./spec/models/user_spec.rb:41:in `block (4 levels) in <top (required)>'
user_spec.rb:
require 'spec_helper'
describe User do
describe "return value of authenticate method" do
user = FactoryGirl.create(:user)
let(:found_user) { User.find_by(email: user.email) }
describe "with valid password" do
it { should eq found_user.authenticate(user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not eq user_for_invalid_password }
specify { expect(user_for_invalid_password).to be_false }
end
end
end
And I'm also using FactoryGirl to generate the username and email addresses but I don't think it has anything to do with the failure:
require 'faker'
FactoryGirl.define do
factory :user do |u|
u.fullname { Faker::Name.name }
u.email { Faker::Internet.email }
u.password { "foobar" }
u.password_confirmation { "foobar" }
end
end

The problem is the way the spec is set up. You're using an implicit subject which, for this spec, will be User.new. That's why you're seeing a User object with all nil attributes.
Your it clauses should read more like
it { found_user.authenticate(user.password).should eq user }
and
it { user_for_invalid_password.should be_nil }
which actually test the behavior.
UPDATE:
With the introduction in RSpec 3.x of expect syntax as the preferred syntax, this would now be:
it { expect(found_user.authenticate(user.password)).to eq user }
and
it { expect(user_for_invalid_password).to be_nil }

Related

RSPEC Error: Expected #<ActiveRecord::Associations::CollectionProxy > got: nil

I am trying to test the following controller action(Using Ruby on Rails, RSPEC, and FactoryGirl):
class ContactsController < ApplicationController
before_action :authenticate_user!
def index
#contacts = current_user.contacts
# #contacts = Contact.all
end
Here is my contacts_controller_spec.rb file:
require 'rails_helper'
describe ContactsController do
before do
#user = FactoryGirl.create(:user_with_contacts)
sign_in #user
end
describe "GET INDEX" do
it "assigns #contacts" do
expect(assigns(:contacts)).to eq(#user.contacts)
end
end
Failure/Error: expect(assigns(:contact)).to eq([contact])
expected: [#<Contact id: 295, first_name: "Loy", email: "leon#hegmannhintz.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Wyman", user_id: 343>]
got: #<Contact id: nil, first_name: nil, email: nil, phone_number: nil, created_at: nil, updated_at: nil, last_name: nil, user_id: nil>
And here is my users_spec.rb file:
FactoryGirl.define do
factory :user do
email { Faker::Internet.email }
password { "32423fdsfasf42" }
factory :user_with_contacts do
transient do
contacts_count 2
end
after(:create) do |user, evaluator|
create_list(:contact, evaluator.contacts_count, user: user)
end
end
end
end
Any Help please? I have been stuck on this for a long time.
If i call
puts #user.inspect
I get
#<User id: 340, email: "johnson_kaulke#brekke.com", encrypted_password: "$2a$04$Si5k6Q1eYERvhQITXKBoIOGEzPyK50E3IQ.yjRcqmDj...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42">
and
calling
puts #user.contacts.inspect
I get
#<ActiveRecord::Associations::CollectionProxy [#<Contact id: 289, first_name: "Fae", email: "ariane#johnston.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Spinka", user_id: 340>, #<Contact id: 290, first_name: "Marcellus", email: "chloe_deckow#buckridge.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Bashirian", user_id: 340>]>
Its just when i call the assigns(:contacts) that the problem happens!
I think you forgot to invoke the controller action. :)
Try adding get :index
it "assigns #contacts" do
get :index
expect(assigns(:contacts)).to eq(#user.contacts)
end

Controller spec .reload error: no implicit conversion of nil into Hash

My rspec tests are failing when I try to use .reload to test the Update method.
The error
Admin::CompaniesController PUT update valid attributes changes #company's attributes
Failure/Error: #company.reload
TypeError:
no implicit conversion of nil into Hash
# ./spec/controllers/admin/admin_companies_controller_spec.rb:81:in `block (4 levels) in <top (required)>'
The spec
# spec/controllers/admin_companies_controller_spec.rb
describe 'PUT update' do
before :each do
#company = create(:company, name: "Rockstars", phone: "3035551212")
end
context "valid attributes" do
it "changes #company's attributes" do
put :update, id: #company, company: attributes_for(:company, name: "Fishstars")
#company.reload #line 81
expect( #company.name ).to eq("Fishstars")
end
end
end
I have also tried (1) using let!(), (same error)
describe 'PUT update' do
let!(:company) { create(:company, name: "Rockstars", phone: "303555121d") }
context "valid attributes" do
it "changes company's attributes" do
put :update, id: company, company: attributes_for(:company, name: "Fishstars")
company.reload #line 81
expect( company.name ).to eq("Fishstars")
end
end
end
I have also tried (2) (same error)
before :each do
#company = create(:company, name: "Rockstars", phone: "3035551212")
end
it "changes #company's attributes" do
#attr = { name: "Fishstars" }
put :update, id: #company.id, :company => #attr
#company.reload
expect( #company.name ).to eq("Fishstars")
end
My first thought was that the variable #company was nil, but if I comment out line 81 (indicated) the test fails as expected.
Update
inserting 'byebug' just before line 81 allows me to see what #company looks like:
(byebug) #company
#<Company id: 1, name: "Rockstars", hq_address: "MyString", hq_city: "MyString", hq_state: "MyString", country: "MyString", description: "Description 1", phone: "3035551212", email: "Example2email#gmail.com", owner_id: 2, contact_name: "MyString", created_at: "2014-07-11 19:02:24", updated_at: "2014-07-11 19:02:24", active: true, logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil, slug: "rockstars", refund_policy: "Refund policy">
(byebug) #company.reload
TypeError Exception: no implicit conversion of nil into Hash
nil
I wasn't able to figure out why .reload wasn't working, but I replaced it with a find_by_id call and my tests are working properly now:
# new code - effectively tests the update method
#company = Company.find_by_id(#company)
# original code - causes errors
#company.reload #line 81

ActionController::RoutingError: No route matches

I am a bit of a freshman in rails, so please bear with me.
I get a routing error on my tests. The tests are as follwoing:
require 'spec_helper'
describe "ProducerPages" do
subject { page }
describe "profile page" do
#producer = Producer.create(name:"Example Producer",
email: "producer#example.com", password: "foobar",
password_confirmation: "foobar")
before { visit producer_path(#producer) }
it { should have_selector('h1', text: producer.name) }
it { should have_selector('title', text: producer.name) }
end
end
and the failure produced is:
Failures:
1) ProducerPages profile page
Failure/Error: before { visit producer_path(#producer) }
ActionController::RoutingError:
No route matches {:action=>"show", :controller=>"producers", :id=>nil}
# ./spec/requests/producer_pages_spec.rb:14:in `block (3 levels) in <top (required)>'
It looks, I do something wrong with creating the producer instance variable. I tried to make that a normal variable, but then I get this error:
1) ProducerPages profile page
Failure/Error: before { visit producer_path(producer) }
ActionController::RoutingError:
No route matches {:action=>"show", :controller=>"producers",
:id=>#<Producer id: nil, name: "Example Producer",
email: "producer#example.com", created_at: nil, updated_at: nil,
password_digest: "$2a$04$pXAEklj4nzYe48ojR5Ps/Oh8Ea9.QqKOajYBD2Rv0mQ9...",
remember_token: nil, admin: false, oid: nil, contact_name: nil,
street: nil, postal_code: nil, city: nil, country: nil, url: nil,
telephone: nil, cellular: nil, type: "Producer", producer_id: nil,
client_key: nil, product_count: 0>}
# ./spec/requests/producer_pages_spec.rb:14:in `block (3 levels) in <top (required)>'
the routes.rb file contains
resources :producers
What am I doing wrong?

Association clears when reloading a record in test

I am only familiar with Rspec, but now I need to fix a library which uses Test::Unit.
I find out that when I reload the record, the association becomes nil
For example:
test "accepts nested attributes from subscription to user ()" do
#user = User.create(name:'Ash')
#subscription = #user.create_subscription()
puts "user: " << #user.inspect
puts "subscription: " << #user.subscription.inspect
#subscription.update_attributes({ :user_attributes => { :notification_comment => true } })
#user.reload
puts "user: " << #user.inspect
puts "subscription: " << #user.subscription.inspect
assert #user.subscription, "should have an subscription"
end
Outputs:
user: #<User id: 815823837, account_id: nil, name: "Ash", email: nil, settings: {}, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
subscription: #<Subscription id: 1, user_id: 815823837, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
user: #<User id: 815823837, account_id: nil, name: "Ash", email: nil, settings: {}, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
subscription: nil
Why does this happen? I did check and I can confirm that I can Subscription.find(#subscription.id) so it is saved in the database.

Failing rspec test -- object is not being created

I have the following test code:
require 'spec_helper'
require 'matchers/be_valid_verbose'
describe User do
before do
#user = User.new(first_name: "First", last_name: "Last", email: "test#test.com", role: "admin",
password: "foobar12", password_confirmation: "foobar12")
end
subject ( #user )
specify { should be_valid_verbose }
describe "return value of authendicate method" do
before { #user.save }
let(:found_user) { User.find_by_email(#user.email) }
describe "with valid password" do
it { should == found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invlaid") }
it { should_not == user_for_invalid_password }
specify { user_for_invalid_password.should be_false }
end
end
end
I don't understand why: it { should be_valid } is gettig a totally empty user object. The same is happening when I try to find_by_email after just creating the user object in the before do statement.
Here's my test output
$ bundle exec rspec spec/models/user_trial_spec.rb
FF..
Failures:
1) User
Failure/Error: specify { should be_valid_verbose }
expected valid? to return true, got false:
Password digest can't be blank
First name can't be blank
Last name can't be blank
Role is not included in the list
Email can't be blank
Email is invalid
Password can't be blank
Password is too short (minimum is 8 characters)
Password confirmation can't be blank
# ./spec/models/user_trial_spec.rb:25:in `block (2 levels) in <top (required)>'
2) User return value of authendicate method with valid password
Failure/Error: it { should == found_user.authenticate(#user.password) }
expected: #<User id: 10, first_name: "First", last_name: "Last", email: "test#test.com", role: "admin", password_digest: "$2a$10$Z0c6zJNH4yu8IpYfNqEbKOmqEWK.euTFcYuwB/8UW9jk...", created_at: "2012-11-13 21:44:55", updated_at: "2012-11-13 21:44:55", remember_token: nil>
got: #<User id: nil, first_name: nil, last_name: nil, email: nil, role: nil, password_digest: nil, created_at: nil, updated_at: nil, remember_token: nil> (using ==)
Diff:
## -1,2 +1,2 ##
-#<User id: 10, first_name: "First", last_name: "Last", email: "test#test.com", role: "admin", password_digest: "$2a$10$Z0c6zJNH4yu8IpYfNqEbKOmqEWK.euTFcYuwB/8UW9jk...", created_at: "2012-11-13 21:44:55", updated_at: "2012-11-13 21:44:55", remember_token: nil>
+#<User id: nil, first_name: nil, last_name: nil, email: nil, role: nil, password_digest: nil, created_at: nil, updated_at: nil, remember_token: nil>
# ./spec/models/user_trial_spec.rb:32:in `block (4 levels) in <top (required)>'
Finished in 2.3 seconds
4 examples, 2 failures
Failed examples:
rspec ./spec/models/user_trial_spec.rb:25 # User
rspec ./spec/models/user_trial_spec.rb:32 # User return value of authendicate method with valid password
Randomized with seed 39450
Okay i just saw the problem. I was using
subject ( #user )
instead of the correct
subject { #user }
DOH!

Resources