FactoryGirl: why does attributes_for omit some attributes?

前端 未结 5 1304
借酒劲吻你
借酒劲吻你 2020-12-03 10:57

I want to use FactoryGirl.attributes_for in controller testing, as in:

it \"raise error creating a new PremiseGroup for this user\" do
  expect {
    post :c         


        
5条回答
  •  被撕碎了的回忆
    2020-12-03 11:47

    Short Answer:

    By design, FactoryGirl's attribues_for intentionally omits things that would trigger a database transaction so tests will run fast. But you can can write a build_attributes method (below) to model all the attributes, if you're willing to take the time hit.

    Original answer

    Digging deep into the FactoryGirl documentation, e.g. this wiki page, you will find mentions that attributes_for ignores associations -- see update below. As a workaround, I've wrapped a helper method around FactoryGirl.build(...).attributes that strips id, created_at, and updated_at:

    def build_attributes(*args)
      FactoryGirl.build(*args).attributes.delete_if do |k, v| 
        ["id", "created_at", "updated_at"].member?(k)
      end
    end
    

    So now:

    >> build_attributes(:premise_group)
    => {"name"=>"PremiseGroup_21", "user_id"=>29, "is_visible"=>false, "is_open"=>false}
    

    ... which is exactly what's expected.

    update

    Having absorbed the comments from the creators of FactoryGirl, I understand why attributes_for ignores associations: referencing an association generates a call to the db which can greatly slow down tests in some cases. But if you need associations, the build_attributes approach shown above should work.

提交回复
热议问题