Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialJacqueline Boltik
Courses Plus Student 11,153 PointsWhy are my spec tests failing when they should be passing?
I started building my app using guard/minitest and then decided to switch over to rspec. I added rspec to my gemfile for test and development (below)
group :development, :test do
gem 'byebug'
gem 'web-console'
gem 'spring'
gem 'annotate'
gem 'rspec-rails'
end
group :test do
gem 'minitest-reporters'
gem 'mini_backtrace'
gem 'guard-minitest'
end
I bundle installed and saw the new spec directory. But for some reason that I have not been able to figure out some tests are failing that should be passing.
Here's my user_spec.rb in spec/models/user_spec.rb
require 'rails_helper'
#RSpec.describe User, :type => :model do
# pending "add some examples to (or delete) #{__FILE__}"
describe User do
let(:valid_attributes) {
{
first_name: "Jacqueline",
last_name: "Boltik",
email: "jboltik@oolaabox.com",
password: "password",
password_confirmation: "password"
}
}
context "validations" do
let(:user) { User.new(valid_attributes) }
before do
User.create(valid_attributes)
end
it "requires an email" do
expect(user).to validate_presence_of(:email)
end
it "requires a unique email" do
expect(user).to validate_uniqueness_of(:email)
end
it "requires a unique email (case insensitive)" do
user.email = "JBOLTIK@OOLAABOX.COM"
expect(user).to validate_uniqueness_of(:email)
end
it "requires the email address to look like an email" do
user.email = "jboltik"
expect(user).to_not be_valid
end
end
describe "#downcase_email" do
it "makes the email attribute lower case" do
user = User.new(valid_attributes.merge(email: "JBOLTIK@OOLAABOX.COM"))
expect{ user.downcase_email }.to change{ user.email }.
from("JBOLTIK@OOLAABOX.COM").
to("jboltik@oolaabox.com")
end
it "downcases an email before saving" do
user = User.new(valid_attributes)
user.email = "MIKE@TEAMTREEHOUSE.COM"
expect(user.save).to be_true
expect(user.email).to eq("mike@teamtreehouse.com")
end
end
end
And here's the model user.rb in app/models/user.rb
class User < ActiveRecord::Base
has_secure_password
validates :email, presence: true,
uniqueness: true,
format: {
with: /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/
}
before_save :downcase_email
def downcase_email
self.email = email.downcase
end
end
When I run the test $ rspec spec/models/user_spec.rb
it returns two passing tests and 4 failures. I copied the code directly from the exercise and I can't figure out why it's failing. I'm using Rails 4.1 Ruby 2.1 and Rspec 3.1
Thank you in advance for any help!
5 Answers
Maciej Czuchnowski
36,441 PointsIt's only my preliminary theory but you might need the shoulda-matchers gem which gives you those validate_uniqueness_of tests.
Jacqueline Boltik
Courses Plus Student 11,153 PointsThe final test passed by changing
it "downcases an email before saving" do
user = User.new(valid_attributes)
user.email = "JBOLTIK@OOLAABOX.COM"
expect(user.save).to be_true
expect(user.email).to eq("jboltik@oolaabox.com")
end
to
it "downcases an email before saving" do
user = User.new(valid_attributes)
user.email = "JBOLTIK@OOLAABOX.COM"
expect(user.save).to be true
expect(user.email).to eq("jboltik@oolaabox.com")
end
Now everything passes :) Seems like a change in syntax with Rspec 3 was causing the issue.
Maciej Czuchnowski
36,441 PointsGlad this worked :). Yeah, RSpec 3 introduced some changes in the syntax. I used be_truthy
in case of similar test.
Maciej Czuchnowski
36,441 PointsAlthough truthy will accept ANY value that is not nil
or false
, so it's not always preferable.
Janis Celms
44,170 PointsRspec 3 new syntax was failing me as well
Jacqueline Boltik
Courses Plus Student 11,153 PointsHere's the entire console output. Thanks for your help!
$ rspec spec/models/user_spec.rb
WARNING: Nokogiri was built against LibXML version 2.9.2, but has dynamically loaded 2.9.0
FFF..F
Failures:
1) User validations requires an email
Failure/Error: expect(user).to validate_presence_of(:email)
NoMethodError:
undefined method `validate_presence_of' for #<RSpec::ExampleGroups::User::Validations:0x007fe14bd9d468>
# ./spec/models/user_spec.rb:23:in `block (3 levels) in <top (required)>'
2) User validations requires a unique email
Failure/Error: expect(user).to validate_uniqueness_of(:email)
NoMethodError:
undefined method `validate_uniqueness_of' for #<RSpec::ExampleGroups::User::Validations:0x007fe150467c90>
# ./spec/models/user_spec.rb:27:in `block (3 levels) in <top (required)>'
3) User validations requires a unique email (case insensitive)
Failure/Error: expect(user).to validate_uniqueness_of(:email)
NoMethodError:
undefined method `validate_uniqueness_of' for #<RSpec::ExampleGroups::User::Validations:0x007fe14a589d68>
# ./spec/models/user_spec.rb:32:in `block (3 levels) in <top (required)>'
4) User#downcase_email downcases an email before saving
Failure/Error: expect(user.save).to be_true
expected true to respond to `true?`
# ./spec/models/user_spec.rb:53:in `block (3 levels) in <top (required)>'
Finished in 0.11439 seconds (files took 2.38 seconds to load)
6 examples, 4 failures
Failed examples:
rspec ./spec/models/user_spec.rb:22 # User validations requires an email
rspec ./spec/models/user_spec.rb:26 # User validations requires a unique email
rspec ./spec/models/user_spec.rb:30 # User validations requires a unique email (case insensitive)
rspec ./spec/models/user_spec.rb:50 # User#downcase_email downcases an email before saving
Jacqueline Boltik
Courses Plus Student 11,153 PointsGreat advice - I just installed the shoulda_matchers gem and now the tests pass all except 1. I followed the instructions to install shoulda_matchers here - in case anyone else is facing this same issue the instructions are very clear: https://github.com/thoughtbot/shoulda-matchers#rspec
After installing shoulda_matchers I retested and only got 1 failure.
$ rspec spec/models/user_spec.rb
WARNING: Nokogiri was built against LibXML version 2.9.2, but has dynamically loaded 2.9.0
.....F
Failures:
1) User#downcase_email downcases an email before saving
Failure/Error: expect(user.save).to be_true
expected true to respond to `true?`
# ./spec/models/user_spec.rb:53:in `block (3 levels) in <top (required)>'
Finished in 0.20742 seconds (files took 3.7 seconds to load)
6 examples, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:50 # User#downcase_email downcases an email before saving
Rachel Klein
7,388 PointsThanks for posting your solution, Jacqueline! You helped me solve the same problem.
Maciej Czuchnowski
36,441 PointsMaciej Czuchnowski
36,441 PointsPlease copy the whole failing output from the console. It will tell us which lines in the tests are not passing and why.