Hello I''m wondering if someone can put me back on the right track? I''ve started playing with Rails for the last 2 days while reading through the Agile Web Dev with Rails book. I''m in Chapter 7 - Unit Testing and Validation. The book demos work fine, but I''m now also doing my own sample app to reinforce what I''m reading at the same time. I''m trying to do some Unit Tests on my User Model to check the length of the password attribute. Some of the assertions are failing unexpectedly and I''m now at a loss. Can someone please help me find what I''m overlooking? Here''s the Terminal output from running the Unit Tests: ******************************** turgs:snapshots tim$ rake test:units Loaded suite /usr/local/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/ rake_test_loader Started ....FF. Finished in 0.531600 seconds. 1) Failure: test_Password_must_be_long_enough(UserTest) [/users/tim/Sites/ snapshots/test/unit/user_test.rb:31]: Failed assertion, no message given. 2) Failure: test_Password_must_be_shorter(UserTest) [/users/tim/Sites/snapshots/ test/unit/user_test.rb:47]: Failed assertion, no message given. 7 tests, 25 assertions, 2 failures, 0 errors, 0 skips Test run options: --seed 21159 rake aborted! Command failed with status (1): [/usr/local/bin/ruby -I"lib:test" "/ usr/loc...] Tasks: TOP => test:units (See full trace by running task with --trace) turgs:snapshots tim$ ******************************** Here''s the User model code: ******************************** class User < ActiveRecord::Base has_many :accounts, :dependent => :destroy validates :email, :presence => true validates :name, :presence => true validates :password, :presence => true, :length => { :minimum => 8, :maximum => 2000, :message => ''should be between 8 and 2000 characters'' } validates :security_question, :presence => true validates :security_answer, :presence => true validates :mobile_phone, :length => { :minimum => 8, :maximum => 30, :message => ''should be between 8 and 30 characters''} end ******************************** Here''s the Unit Test user_test.rb file: ******************************** require ''test_helper'' class UserTest < ActiveSupport::TestCase test "User attributes must not be empty" do user = User.new assert user.invalid? assert user.errors[:email].any? assert user.errors[:name].any? assert user.errors[:password].any? assert user.errors[:security_question].any? assert user.errors[:security_answer].any? assert user.errors[:mobile_phone].any? end test "Password must be long enough" do user = User.new(:email => "adam-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", :name => "Adam", :security_question => "What''s my name?", :security_answer => "Adam") user.password = "1234567" assert user.invalid? assert_equal "should be between 8 and 2000 characters", user.errors[:password].join(''; '') user.password = "12345678" assert user.valid? # this assertion is failing user.password = "123456789" assert user.valid? end test "Password must be shorter" do user = User.new(:email => "eve-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", :name => "Eve", :security_question => "What''s my name?", :security_answer => "Eve") user.password = "12345678901234567890...01234567890123456789" # this is 1999 chars long, I''ve just cut it for this email. assert user.valid? # this assertion is failing user.password = "12345678901234567890...012345678901234567890" # this is 2000 chars long, I''ve just cut it for this email. assert user.valid? user.password = "12345678901234567890...0123456789012345678901" # this is 2001 chars long, I''ve just cut it for this email. assert user.invalid? assert_equal ''should be between 8 and 2000 characters'', user.errors[:password].join(''; '') end end ******************************** Any help would be greatly appreciated. Cheers Tim -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
(comments inline) On Aug 31, 2011, at 11:22 PM, Turgs wrote:> Hello > > I''m wondering if someone can put me back on the right track? > > I''ve started playing with Rails for the last 2 days while reading > through the Agile Web Dev with Rails book. I''m in Chapter 7 - Unit > Testing and Validation. The book demos work fine, but I''m now also > doing my own sample app to reinforce what I''m reading at the same > time. > > I''m trying to do some Unit Tests on my User Model to check the length > of the password attribute. > > Some of the assertions are failing unexpectedly and I''m now at a loss. > Can someone please help me find what I''m overlooking? > > Here''s the Terminal output from running the Unit Tests: > > > ******************************** > > turgs:snapshots tim$ rake test:units > Loaded suite /usr/local/lib/ruby/gems/1.9.1/gems/rake-0.9.2/lib/rake/ > rake_test_loader > Started > ....FF. > Finished in 0.531600 seconds. > > 1) Failure: > test_Password_must_be_long_enough(UserTest) [/users/tim/Sites/ > snapshots/test/unit/user_test.rb:31]: > Failed assertion, no message given. > > 2) Failure: > test_Password_must_be_shorter(UserTest) [/users/tim/Sites/snapshots/ > test/unit/user_test.rb:47]: > Failed assertion, no message given. > > 7 tests, 25 assertions, 2 failures, 0 errors, 0 skips > > Test run options: --seed 21159 > rake aborted! > Command failed with status (1): [/usr/local/bin/ruby -I"lib:test" "/ > usr/loc...] > > Tasks: TOP => test:units > (See full trace by running task with --trace) > turgs:snapshots tim$ > > ******************************** > > > Here''s the User model code: > > > ******************************** > > class User < ActiveRecord::Base > has_many :accounts, :dependent => :destroy > > validates :email, :presence => true > validates :name, :presence => true > validates :password, :presence => true, :length => > { :minimum => 8, :maximum => 2000, :message => ''should be between 8 > and 2000 characters'' } > validates :security_question, :presence => true > validates :security_answer, :presence => true > validates :mobile_phone, :length => > { :minimum => 8, :maximum => 30, :message => ''should be between 8 and > 30 characters''} > > end > > ******************************** > > > Here''s the Unit Test user_test.rb file: > > > ******************************** > > require ''test_helper'' > > class UserTest < ActiveSupport::TestCase > > test "User attributes must not be empty" do > user = User.new > assert user.invalid? > assert user.errors[:email].any? > assert user.errors[:name].any? > assert user.errors[:password].any? > assert user.errors[:security_question].any? > assert user.errors[:security_answer].any? > assert user.errors[:mobile_phone].any? > end > > > test "Password must be long enough" do > user = User.new(:email => "adam-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", > :name => "Adam", > :security_question => "What''s my name?", > :security_answer => "Adam") > > user.password = "1234567" > assert user.invalid? > assert_equal "should be between 8 and 2000 characters", > user.errors[:password].join(''; '') > > user.password = "12345678" > assert user.valid? # this assertion is failingThis test is meant to test one thing -- that a password must be at least 8 characters. Testing "user.valid?" tests much more than that. That could be false for any number of reasons -- perhaps you have a validation that rejects "example.com" as a valid email address. I would test that at least one error exists on the :password attribute for the user and if you want, take it a step farther and test that the type of error is :too_short (see 5.1.2 of http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models for what i''m talking about) I would also break this up into individual tests... test "user is invalid when password is too short" test "user is invalid when password is too long" test "user is valid when password is just right"> user.password = "123456789" > assert user.valid? > > end > > > test "Password must be shorter" do > user = User.new(:email => "eve-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", > :name => "Eve", > :security_question => "What''s my name?", > :security_answer => "Eve") > > user.password = "12345678901234567890...01234567890123456789" # > this is 1999 chars long, I''ve just cut it for this email.You might try this for readability. user.password = "x" * 1999 # results in a string of x''s of length 1999. Good luck!> assert user.valid? # this assertion is failing > > user.password = "12345678901234567890...012345678901234567890" # > this is 2000 chars long, I''ve just cut it for this email. > assert user.valid? > > user.password = "12345678901234567890...0123456789012345678901" # > this is 2001 chars long, I''ve just cut it for this email. > assert user.invalid? > assert_equal ''should be between 8 and 2000 characters'', > user.errors[:password].join(''; '') > > end > > end > > ******************************** > > > Any help would be greatly appreciated. > > Cheers > Tim > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. > For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Turgs wrote in post #1019574:> > test "Password must be long enough" do > user = User.new(:email => "adam-hcDgGtZH8xNBDgjK7y7TUQ@public.gmane.org", > :name => "Adam", > :security_question => "What''s my name?", > :security_answer => "Adam") > > user.password = "1234567" > assert user.invalid? > assert_equal "should be between 8 and 2000 characters", > user.errors[:password].join(''; '') > > user.password = "12345678" > assert user.valid? # this assertion is failingIs the mobile phone number between 8 and 30 characters? You can write the length validations more succinctly: validates :password, :presence => true, :length => 8..2000 And to form the strings to test against, I hope you are not writing them out by hand: user.password = ("123456790" * 200).chop assert user.valid? # this assertion is failing user.password = "1234567890" * 200 user.password = ("1234567890" * 200) + ''1'' assert user.invalid? #assert_equal ''should be between 8 -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Philip Hallstrom wrote in post #1019611:> > could be false for any number of reasons -- perhaps you have a > validation that rejects "example.com" as a valid email address. >Does he? Here''s his model: class User < ActiveRecord::Base has_many :accounts, :dependent => :destroy validates :email, :presence => true validates :name, :presence => true validates :password, :presence => true, :length => { :minimum => 8, :maximum => 2000, :message => ''should be between 8 and 2000 characters'' } validates :security_question, :presence => true validates :security_answer, :presence => true validates :mobile_phone, :length => { :minimum => 8, :maximum => 30, :message => ''should be between 8 and 30 characters''} end -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Instead of using "user.valid?", how can I make it more specific so I''m just testing the password attribute? On Sep 2, 1:30 am, Philip Hallstrom <phi...-LSG90OXdqQE@public.gmane.org> wrote:> This test is meant to test one thing -- that a password must be at least 8 characters. Testing "user.valid?" tests much more than that. That could be false for any number of reasons -- perhaps you have a validation that rejects "example.com" as a valid email address. > > I would test that at least one error exists on the :password attribute for the user-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
assert user.errors[:password].empty? -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
7stud -- wrote in post #1019720:> > Also note that this test doesn''t do what it''s advertised to do: > > > test "User attributes must not be empty" do > user = User.new > assert user.invalid? > assert user.errors[:email].any? > assert user.errors[:name].any? > assert user.errors[:password].any? > assert user.errors[:security_question].any? > assert user.errors[:security_answer].any? > assert user.errors[:mobile_phone].any? > end > > > Because some attributes have validations other than :presence, an error > does not mean the attribute was missing. >Actually, it''s worse than that. Suppose all the attributes were empty. That test would pass, and therefore one would think from the title of the test, that the User''s attributes were all present.> I think you are going about your testing all wrong. Instead, you should > create users that have something wrong with them to test if the > validations catch the errors. For instance, > > test "User''s name cannot be blank" do > #create user with blank name > assert user.valid? > end > > It might save some typing to setup each test with a valid user, and > inside the test change one attribute to something that isn''t valid. > > Read section 3 and section 8 of the railsguide on testing here: > > http://guides.rubyonrails.org/testing.html-- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Sep 1, 2011, at 9:13 AM, 7stud -- wrote:> Philip Hallstrom wrote in post #1019611: >> >> could be false for any number of reasons -- perhaps you have a >> validation that rejects "example.com" as a valid email address. >> > > Does he? Here''s his model:No, he doesn''t. Sorry, I should have been more clear. The problem with using valid? is that at some point he *may* add a validation that causes the user to be invalid even though the password is *okay*. Now you''ve got a test for password failing even though the password is okay and that leads to madness :)> class User < ActiveRecord::Base > has_many :accounts, :dependent => :destroy > > validates :email, :presence => true > validates :name, :presence => true > validates :password, :presence => true, :length => > { :minimum => 8, :maximum => 2000, :message => ''should be between 8 > and 2000 characters'' } > validates :security_question, :presence => true > validates :security_answer, :presence => true > validates :mobile_phone, :length => > { :minimum => 8, :maximum => 30, :message => ''should be between 8 and > 30 characters''} > > end > > -- > Posted via http://www.ruby-forum.com/. > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. > For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.