Reputation: 4787
I'm building a daily deal rails app and I have followed M. Hartl tutorial to set some rspec tests.
For users they work perfectly.
But now I have used it for the model Eals and all are passing, when they shouldn't. For example, in my models, I put that titles can't be longer than 200 characters (note:on my view, when I try to set titles longer than this, it works and alerts me it's not possible)
But when I do tests no matter if I try for the title character length's test with long = "a" * 50, a * 201 or even a * 10000 in the title test, it always pass! There is a big problem I don't manage to find. And actually all the other tests have the same problem: they always pass!
Here is my models/deal.rb
class Deal < ActiveRecord::Base
belongs_to :admin_user
attr_accessible :url_path,
:country,
:title,
:description,
:twitter_msg,
:admin_user_id
validates :url_path,
presence: true,
uniqueness: { :case_sensitive => false }
validates :country,
:inclusion => { :in => ['France', 'Germany', 'United States'],
:message => "%{value} is not a valid country. " }
validates :title,
presence: true,
length: { maximum: 200,
:message => "Your title has %{value} characters but must be shorter than 200 characters" }
validates :description,
presence: true,
length: { maximum: 500,
:message => "Your title has %{value} characters but must be shorter than 500 characters" }
validates :twitter_msg,
presence: true,
uniqueness: { :case_sensitive => false }
validates :admin_user_id, presence: true
And my deal_spec.rb:
require 'spec_helper'
describe Deal do
let(:admin_user) { FactoryGirl.create(:admin_user) }
before (:each) do
@attr = { url_path: "lorem ipsum",
country:"France",
title: "lorem ipsum",
description:"lorem ipsum",
twitter_msg:"lorem ipsum",
}
end
it { should respond_to(:url_path) }
it { should respond_to(:country) }
it { should respond_to(:title) }
it { should respond_to(:description) }
it { should respond_to(:twitter_msg) }
describe "title test" do
it "should reject deals with title that is too long" do
long = "a" * 50
hash = @attr.merge(:title => long)
Deal.new(hash).should_not be_valid
end
[other tests]
end #end of title test
If anybody can help me understand that, that would be great, I have been spending hours without any clue.
After following sb advice, I changed my test with
Deal.new(hash).should have(1).error_on(:title)
describe "test" do
it "should reject games with title that is too long" do
long = "a" * 250
hash = @attr.merge(:title => long)
Game.new(hash).should have(1).error_on(:title)
end
end
But now it's passing all the time, i.e it's telling me I have one error on title no matter if I put long= "a" * 5, long="a" * 300...
Upvotes: 1
Views: 600
Reputation: 106792
Could you please try the following code? It should give you a hint what attribute is invalid (and why):
it "..." do
d = Deal.new(@attr)
d.valid?
puts d.errors.full_messages
end
Upvotes: 1
Reputation: 901
I recommend using shoulda_matchers for testing such things
Upvotes: 1
Reputation: 51697
This is not the correct way to test validation using RSpec because it doesn't tell you why the object is invalid. It may be invalid because you're missing a totally different attribute that the one you're testing for. You should be using the have(x).errors_on(y)
assertion:
Deal.new(hash).should have(1).error_on(:title)
Upvotes: 4
Reputation:
admin_user_id
is not in your @attr
hash. However it's mandatory on your Deal
model - so your test always passes because the new deal is not valid. Nothing to do with the length of the title.
Upvotes: 0