Factory Girl 什么时候在数据库中创建对象?

26

我正在尝试使用 FactoryGirl/shoulda 进行会话模拟(这在使用固定装置时是奏效的,但我在使用工厂时遇到了问题)。我拥有以下工厂(用户登录和电子邮件都具有 unique 验证):

Factory.define :user do |u| 
 u.login 'quentin'
 u.email 'quentin@example.com'
end

Factory.define :session_user, :class => Session do |ses| 
 ses.association :user, :factory => :user
 ses.session_id 'session_user'
end

这里是测试内容

class MessagesControllerTest < ActionController::TestCase

 context "normal user" do
  setup do 
   @request.session[:user_id]=Factory(:user).id
   @request.session[:session_id]=Factory(:session_user).session_id
  end

  should "be able to access new message creation" do
   get :new
   assert_response :success
  end
 end
end

但是当我运行rake test:functionals时,我得到了这个测试结果。

 1) Error: 
  test: normal user should be able to access new message creation. (MessagesControllerTest):
  ActiveRecord::RecordInvalid: Validation failed: Account name already exists!, Email already exists!

这意味着当我在测试设置中引用它时,记录已经存在于数据库中。这里有些我不理解的东西吗?FactoryGirl是否在启动时创建所有工厂?

rails 2.3.5/shoulda/FactoryGirl

1个回答

38

Factory(:user)Factory.create(:user)的快捷方式,因此在设置中,您正在创建两个对象并将它们保存到数据库。

Factory.build(:user)会为您创建一个不保存到数据库中的user记录。

编辑

在您的session_user工厂内,您正在创建一个用户,然后在测试设置内再次创建另一个用户。由于您在session_user工厂中有关联,因此FactoryGirl将创建一个新的user记录。

您可以按以下方式从session_user对象获取您的user实例:

 context "normal user" do
  setup do
   session = Factory(:session_user)  
   @request.session[:session_id] = session.session_id
   @request.session[:user_id] = session.user_id
  end

或者你可以向user工厂添加一些细节,以确保唯一的名称和电子邮件地址,如下所示:

Factory.define :user do |u| 
 u.sequence(:login) {|n| "quentin#{n}" }
 u.sequence(:email) {|n| "quentin#{n}@example.com"}
end

1
但是我的代码中只有一个Factory(:user)的提及,为什么它会运行两次?(第二个是Factory(:session_user),它是一个Session实例) - Pavel K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接