Rails: Test::Unit Why do I need to assert if something is valid or invalid before any other asserts
This seems a little weird, when running a unit test to check if the length of my title is > 10 my test will pass if I include "assert product.invalid?" before any my other assert like this:
require 'test_helper'
class ProductTest < ActiveSupport::TestCase
test "product title is too short" do
product = Product.new(:title => "My lady",
:description => "yyy",
:price => 1
)
assert product.invalid?
assert_equal "must be atleast 10 characters long.", product.errors[:title].join('; ')
end
end
However if I don't include "assert product.inva开发者_运维技巧lid?" before assert_equal I get this error 1) Failure: test_product_title_is_too_short blah blah blah ("must be atleast 10 characters long.") expected but was ("").
Is that how Test::Unit works? I have to assert that something is valid or invalid before I proceed with other tests? Kind of like initializing the test?
This isn't actually a characteristic of your test framework, but rather of ActiveRecord.
When creating an object with ActiveRecord, you can assign validations to ensure certain things about the attributes of the objects (as you have on your object). However, these validations only get run at certain times, and as you're observing, the 'new' method isn't one of these times. However, by asking about the validity of the object with the invalid? method, you have thus triggered the validations.
I think what might be more natural is to use the "create" method instead of 'new' to trigger validations for your object. create checks validations automatically which will eliminate your call to "invalid?" in your test and should still populate the errors hash as desired:
product = Product.create(:title => "My lady",
:description => "yyy",
:price => 1
)
assert_equal "must be atleast 10 characters long.", product.errors[:title].join('; ')
Similarly to the 'create' method is the 'create!' method which will actually raise an exception if any validations fail. create will simply return false and populate the error hash.
For more info on validations check out: http://guides.rubyonrails.org/active_record_validations_callbacks.html
This has nothing to do with Test::Unit. This is rails functionality. The validations only run when either .valid?
or one of the versions of .save
are called. You can read more about the callback chain here: http://guides.rubyonrails.org/active_record_validations_callbacks.html#when-does-validation-happen
精彩评论