zeto
2009-Apr-28 08:25 UTC
Custom Validation on Many-To-Many Association breaks Unit-Tests
Hi, I have the following situation. I have two models Item and Genre.
A Item has a name and a description. The genres-table contains a list
of possible genres wich can be associated to items. So a Item could be
associated with many genres and a genre could be associated with many
items. A typically n:m-relationship. I use the :has_many-:through
association, because i want do to a kind of on-delete-cascade in
Rails.
My models look as follows:
class Item < ActiveRecord::Base
# n:m relationship between items and genres
has_many :items_genres, :dependent => :destroy
has_many :genres, :through => :items_genres
validates_presence_of :name
validate :must_have_at_least_one_associated_genre
protected
# valdation to ensure, that a item has at least one associated genre
def must_have_at_least_one_associated_genre
# add an error message to the default error messages
errors.add(:genres, "must_be_choosen") if
# if no genre is associated with this item
genres.size <= 0
end
end
I put two validations to the Item. The statement at line 6 make the
name arrtibute mandatory. In addition I would to ensure that a item
has at least one associated genre. So I decided to write a own
validation-method (line 10-17).
class ItemsGenre < ActiveRecord::Base
belongs_to :item
belongs_to :genre
end
class Genre < ActiveRecord::Base
# n:m relationship between genres and items
has_many :items_genres, :dependent => :destroy
has_many :items, :through => :items_genres
end
I added some unit-tests to ensure that the validation works as
aspected. I wrote the following unit-test-methods.
require ''test_helper''
class ItemTest < ActiveSupport::TestCase
def test_should_create_an_item
item = Item.new(
:name => "Item-Name",
:description => "Item-Description"
)
# Assert, that the item is not valid and cannot be saved,
# because there are no genres associated with it
assert !item.valid?
assert !item.save
# Associate two genres with this item
item.genres = Genre.find_all_by_id([genres(:club).id, genres
(:commedy).id])
# Assert, that the item is now valid and can be saved
assert item.valid?
assert item.save
# Check if there are two genres associated with this item
assert_equal 2, item.genres.size
end
def test_should_require_name
# Create an item-object, but set name nil
item = Item.new(
:name => nil,
:description => "Item-Description"
)
# Assert, that the item is not valid and cannot be saved,
# because the name is nil
assert !item.valid?
assert !item.save
end
def test_should_require_description
# Create an item-object, but set name to nil
item = Item.new(
:name => "Item-Name",
:description => nil
)
# Assert, that the item is not valid and cannot be saved,
# because the description is nil
assert !item.valid?
assert !item.save
end
end
The amazing thing is that all tree test-methods pass. But I only have
a validation for the name and the asscociated genres. I do not have a
validation of the description, but the test method for the description
passes.
I found out another thing. If I remove the validate-call in line 8 of
the Item-model, then all test-methods work as aspected.
In this case the test_should_create_an_item- and the
test_should_require_description-method both fail and the
test_should_require_name-method passes.
If I run the application and try to add a new item by the new-form,
all validation works as exspected. So it seems that only the unit-test
are faulty.
I am at a loss. I don´t know what I am doing wrong. Can anyone
reproduce this behavior? Or can anyone tell me how to write a
validation-method to ensure that at least one genre is associated with
an item. Maybe my test-method is wrong.
I hope someone can help me out.
Frederick Cheung
2009-Apr-28 08:32 UTC
Re: Custom Validation on Many-To-Many Association breaks Unit-Tests
On Apr 28, 9:25 am, zeto <z...-aLjoz+b64r16lmGzAMPh1A@public.gmane.org> wrote:> > def test_should_require_description > # Create an item-object, but set name to nil > item = Item.new( > :name => "Item-Name", > :description => nil > ) > # Assert, that the item is not valid and cannot be saved, > # because the description is nil > assert !item.valid? > assert !item.save > end > > end > > The amazing thing is that all tree test-methods pass. But I only have > a validation for the name and the asscociated genres. I do not have a > validation of the description, but the test method for the description > passes.In your test that description should be required you haven''t created any genres, so even though you have no validation for description the validation on genres being present makes the item fail to save. Fred> > I found out another thing. If I remove the validate-call in line 8 of > the Item-model, then all test-methods work as aspected. > In this case the test_should_create_an_item- and the > test_should_require_description-method both fail and the > test_should_require_name-method passes. > > If I run the application and try to add a new item by the new-form, > all validation works as exspected. So it seems that only the unit-test > are faulty. > > I am at a loss. I don´t know what I am doing wrong. Can anyone > reproduce this behavior? Or can anyone tell me how to write a > validation-method to ensure that at least one genre is associated with > an item. Maybe my test-method is wrong. > > I hope someone can help me out.
zeto
2009-Apr-28 12:43 UTC
Re: Custom Validation on Many-To-Many Association breaks Unit-Tests
At first, thank you for your advise. I forgot to associate genres in the description_should_be_required-test-method. And you are right. This test method should fail, but it surprisingly passes. zeto
Colin Law
2009-Apr-28 13:20 UTC
Re: Custom Validation on Many-To-Many Association breaks Unit-Tests
You can always go into must_have_at_least_one_associated_genre with the debugger and find out why it is not failing. 2009/4/28 zeto <zeck-aLjoz+b64r16lmGzAMPh1A@public.gmane.org>> > At first, thank you for your advise. I forgot to associate genres in > the description_should_be_required-test-method. And you are right. > This test method should fail, but it surprisingly passes. > > zeto > > >--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
zeto
2009-Apr-28 14:03 UTC
Re: Custom Validation on Many-To-Many Association breaks Unit-Tests
It is not the must_have_at_least_one_associated_genre-test-method. The test_should_require_description-test-method passes the test, but that method should fail.
Colin Law
2009-Apr-28 14:48 UTC
Re: Custom Validation on Many-To-Many Association breaks Unit-Tests
If I understand correctly you are saying that test_should_require_description is passing when it should fail. The fact that it passes appears to mean that the item is not valid. The question is why is it not valid? It may be that must_have_at_least_one_associated_genre is failing. I would check that first. You could just remove this validation to eliminate it. 2009/4/28 zeto <zeck-aLjoz+b64r16lmGzAMPh1A@public.gmane.org>> > It is not the must_have_at_least_one_associated_genre-test-method. The > test_should_require_description-test-method passes the test, but that > method should fail. > > >--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
zeto
2009-Apr-28 14:57 UTC
Re: Custom Validation on Many-To-Many Association breaks Unit-Tests
If I comment out the validation "validate :must_have_at_least_one_associated_genre" in line 8 of my Item-model all test methods work correctly. That means only the test_should_require_name -test-method passes the test. test_should_create_an_item --> fails, because the validation in line 8 of my Item-model is commented out test_should_require_description --> fails, because there is no validation for description yet Of course the failure is somewhere in the must_have_at_least_one_associated_genre-method in the Item-model, but I cannot figure out where the failure is.
Colin Law
2009-Apr-28 16:29 UTC
Re: Custom Validation on Many-To-Many Association breaks Unit-Tests
Go in with the debugger and have a look at the objects. 2009/4/28 zeto <zeck-aLjoz+b64r16lmGzAMPh1A@public.gmane.org>> > If I comment out the validation > "validate :must_have_at_least_one_associated_genre" in line 8 of my > Item-model all test methods work correctly. That means only the > test_should_require_name -test-method passes the test. > > test_should_create_an_item --> fails, because the validation in > line 8 of my Item-model is commented out > test_should_require_description --> fails, because there is no > validation for description yet > > Of course the failure is somewhere in the > must_have_at_least_one_associated_genre-method in the Item-model, but > I cannot figure out where the failure is. > > >--~--~---------~--~----~------------~-------~--~----~ 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---