1

任何人都可以提出一个更好的方法来使工厂使用预建模型 实例为其关联?例如,以便下面将有可能使用 来定义消息工厂的子项,以致可致电 Factory(:my_message)可替代 Factory(:message,:sender=>@me)DRYER测试与在factory_girl协会

有时候安装哈希比在这个人为的 的例子中涉及更多,或者只是在很多测试中重复使用,以至于将它推入工厂似乎更好。

我能想到的另一种方法是定义一个测试帮助方法 ,如create_message_owned_by(@me),但我希望factory_girl本身有一种方法。

factory_girl工厂:

Factory.define :sender do |s| 
    sender.name "Dummy name" 
end 

Factory.define :message do |msg| 
    msg.text "Dummy text" 
    msg.association :sender 
end 

Factory.define :my_message, :parent=>:message do |msg| 
    msg.text "Dummy text" 
    ### ? what goes here for msg.association :sender ? ### 
end 

MessagesControllerTest摘录(使用早该):

context "on GET /messages" do 
    setup do 
    @me = Factory(:sender) 
    @my_message = Factory(:message,:sender=>@me) 
    @somebody_elses_message = Factory(:message) 
    sign_in_as(@me) 
    get :index 
    end 
    should "only assign my messages" do 
    assert_contains(assigns(:messages), @my_message) 
    assert_does_not_contain(assigns(:messages), @somebody_elses_message) 
    end 
end 

回答

2

我不知道如果这是你在找什么,但如果你第一次创建你的消息可以通过该方式获取发件人并将其分配给@me

@my_message = Factory(:message) 
@me = @my_message.sender 

这有帮助吗?

+0

我没有想到这一点,谢谢。我可以把它看作是其他情况的一个很好的简写,但是例如。这里我们使用了Clearance宝石。 @me倾向于早期建立并重用于一堆对象,所以'@my_message = Factory(:message,:sender => @ me)'表格会更短更清晰。 – 2009-08-15 17:39:51

+0

问题是,是什么让当前用户与其他用户有所不同?它只是被分配给@me变量的事实吗?这超出了工厂的范围,并会引入不明确的依赖关系。 – ryanb 2009-08-15 20:27:22

+1

你是对的。经过反思,在工厂硬编码@me(或类似)是愚蠢的。工厂需要一个参数,它通常以'Factory(:message,:sender => @ me)'形式作为尾随散列。 这似乎将它带回到抽象出像'create_message_owned_by(@me)'这样的帮助程序来包装特定的重复关联设置。 – 2009-08-15 23:34:49

1

忽略创建不明依赖的问题,上面的例子可以使用FactoryGirl 1.2.3中的新回调来处理。现在有after_buildafter_create回调,因此您可以在已创建的对象已经存在于数据库中(并且拥有一个可以抓取的ID等)后对其执行操作。

另请参阅factory_girl邮件列表中的this questionthis thread