32

我正在使用 Rspec (2.11.0) 和 FactoryGirl (4.0.0) 在 Ruby on Rails 3 中执行 TDD/BDD。我有一个 Category 模型的工厂:

FactoryGirl.define "Category" do
  factory :category do
    name "Foo"
  end
end

如果我放弃,在测试环境中创建然后迁移数据库,我会收到此错误:

rake aborted!
Could not find table 'categories'

出现此问题的原因是 FactoryGirl 期望这些表已经存在(出于某种奇怪的原因)。如果我从我的 rails 应用程序中删除 spec 文件夹并执行db:migrate,它可以工作。此外,如果我factory-girl-rails从我Gemfile的标记中标记:require => false它也可以工作(那么我必须评论需要才能运行 rspec)。

我在这里找到了一些关于这个问题的信息:https ://github.com/thoughtbot/factory_girl/issues/88

我做错了什么吗?如何在db:migration任务中“绕过”FactoryGirl 阶段?

4

4 回答 4

79

我认为你需要在 Gemfile 中有这样的工厂女孩​​定义:

  gem 'factory_girl_rails', :require => false

然后你只需要像这样在你的 spec_helper.rb 中使用它:

  require 'factory_girl_rails'

这就是我一直使用这个宝石的方式。除了 spec_helper.rb,您不需要在其他地方使用它。您当前所需的方法是错误的。

于 2012-09-14T13:37:09.603 回答
12

解决此问题的一个简单方法是通过将工厂中的任何模型包装在块中来延迟对它们的评估。所以,而不是这个:

factory :cake do
  name "Delicious Cake"
  frosting Frosting.new(:flavor => 'chocolate')
  filling Filling.new(:flavor => 'red velvet')
end

这样做(注意花括号):

factory :cake do
  name "Delicious Cake in a box"
  frosting { Frosting.new(:flavor => 'chocolate') }
  filling { Filling.new(:flavor => 'red velvet') }
end

如果你有很多工厂,这可能不可行,但它相当简单。另请参见此处

于 2012-12-10T08:28:22.723 回答
3

信息来自: http: //guides.rubyonrails.org/testing.html

当您最终破坏您的测试数据库时(相信我,它会发生),您可以根据开发数据库中定义的规范从头开始重建它。你可以通过运行来做到这一点rake db:test:prepare

以上rake db:migrate在开发环境和更新上运行任何挂起的迁移db/schema.rb。从rake db:test:load当前的db/schema.rb. 在随后的尝试中,最好先运行db:test:prepare,因为它首先检查挂起的迁移并适当地警告您。

rake db:test:clone            Recreate the test database from the current environment’s database schema
rake db:test:clone_structure  Recreate the test database from the development structure
rake db:test:load             Recreate the test database from the current schema.rb
rake db:test:prepare          Check for pending migrations and load the test schema
rake db:test:purge            Empty the test database.
于 2012-09-14T13:39:37.937 回答
1

你不应该做任何这些..我认为问题是你对FactoryGirl.define的论点..

试试这个。

FactoryGirl.define do
   factory :category do
       name "Foo"
   end
end

那应该可以正常工作,并且不会搞砸我的迁移或加载。今天,我必须解决一个问题,即我直接从我的工厂引用了一个模型常量,并且不得不将它放在一个块中来修复问题。

FactoryGirl.define do
   factory :category do
       # this causes unknown table isseus
       # state Category::Active
       # this does not.
       state { Category::Active }
   end
end
于 2013-02-11T22:29:48.577 回答