开发者

Factory Girl testing with Ruby on Rails, dependencies

I am writing some tests with RSpec for a Ruby on Rails application and am running into an issue I can't seem to figure out. I have a bunch of objects that are associated with others and I'm using Factory Girl to create them all. Here's an example of where I am having a problem:

    user = Factory.create(:user)
    package = Factory.build(:package, :user => user)
    item = Factory.create(:item, :package => package)

All packages belong to a user, so the first dependency is rather trivial. Create a user then associate it with a package, no problem. Now here's the problem. My Package model has a validation that says it cannot be created without at least one item in the package. That means I can't use Factory.create on it. It's almost the same as doing @Package.new in my packages_controller.rb, which is fine. Later, I go on to create an item, the problem is, I cannot associate this item with the package because the package has no ID yet.

Is there anyway I can create my package, create an item and save it, then associate the two together once the 开发者_运维技巧package has an id?


Check out associations:

http://github.com/thoughtbot/factory_girl

Associated instances can be generated by using the association method when defining a lazy attribute:

Factory.define :post do |p|
  # ...
  p.author {|author| author.association(:user, :last_name
     'Writely') }   end

That way you can create the required associated item automatically.

You'll want something like:

Factory.define :package do |fac|
  fac.association :item  
end 

That'll look for a Factory named item and try to assign it to the item= relationship.


Your validations are mutually exclusive:

My Package model has a validation that says it cannot be created without at least one item in the package

and:

(1) create my package, (2) create an item and save it, then (3) associate the two together once the package has an id?

You need to allow a package to be created in order for it to get an id. What's invalid about an empty package? Maybe there needs to be some other logic that prevents it from being used further, but it should be possible to create a package before you fill it.


If I got it right, your logic seems a little off. To have a PACKAGE, MUST have ITEM; To have ITEM, MUST have PACKAGE. Atleast one of them must be allowed to be created without the need of the other.

If this helps, here is how you create automatically a dependency on the Factory itself. In this example, Packages depends on User and Item depends on Package. The magic here is the method association.

Of course, you must have your models associtations properly done.

(First, the User Factory)

FactoryGirl.define do
  factory :user do
    name { "Some_Name" }
  end
end

(Then, the package Factory, which depends on User)

FactoryGirl.define do
  factory :package do
    description { "Some_Description" }
    user { association(:user) }
  end
end

(Then, Item, which depends on Package)

FactoryGirl.define do
  factory :item do
    description { "Some_Description" }
    package { association(:package) }
  end
end

Hope it helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜