I am trying to build a test suite for a Rails app, and I'm not sure how to build objects with FactoryGirl (I can move to a different tool if necessary).
The tricky part is that there are have deep nested associations, lets take for example this part of the schema : http://imgur.com/HAUS7kr
Let's say I want to do some tests on the "ItemTracker" model. Now there are 2 approaches :
In order to have a valid object, I will need to build a Connexion, which needs a Token, which needs a Project, etc... Also, I want the ProjectItem's project to be the same as the Token's project. Same thing with Company (on top). I wouldn't want to have 2 different projects or companies created. So I need a way for these objects to share some associations. One drawback of this approach is that I'm not sure how to make not created several associated objects, and I'm also gonna build a ton of objects I don't necessarily need (except for validations)
I could say "for this particular test, the associations are irrelevant, so I'm just gonna create one ItemTracker, without its Connexion or ProjectItem, and do my things with this isolated object". In a general manner, I would just create the objects and associations I actually need. By playing with traits, I found a way to avoid creating the associations if I don't need them. The drawback is that this object will not be valid (there are validations on associations), so every time I'm gonna try to save something on it, I'm gonna have an Exception, which will be a pain in some test cases.
So I guess my question is : what is the best way to set up some objects for testing in this kind of complex object structure ?
Thanks for the feedback ;)
You need to build this whole relation tree anyway, but you can put this into a trait and, in specs, create item tracker with trait with_all_relations
, for example. It would look like this:
FactoryGirl.define do
factory :item_tracker do
...
trait :with_all_relations do
after(:build) do |item_tracker|
company = create(:company)
item = create(:item, company: company)
user = create(:user, company: company)
...
item_tracker.project_item = project_item
item_tracker.connexion = connexion
end
end
end
end
And if you specify no trait, you'll get item tracker without any related models.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With