【问题标题】:FactoryGirl screws up rake db:migrate processFactoryGirl 搞砸了 rake db:migrate 进程
【发布时间】:2012-09-07 13:05:00
【问题描述】:

我正在使用 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

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

rake aborted!
Could not find table 'categories'

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

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

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

【问题讨论】:

    标签: ruby-on-rails rspec rake bdd factory-bot


    【解决方案1】:

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

      gem 'factory_girl_rails', :require => false
    

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

      require 'factory_girl_rails'
    

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

    【讨论】:

    • 这个破坏你的 rake 的异常是 rspec 在你运行测试时应该处理的(所以它会将规范标记为未通过)。你的方法是错误的,因为它不能按照你想要的方式工作。
    • 我遇到了这个确切的问题并解决了它 - 非常感谢!
    • 迷你裙宝石也遇到了同样的问题。这个答案也解决了它在迷你裙中。
    • @VadimChumel 你介意解释一下为什么添加 :require => false 会使错误消失吗?我在 repo 中找不到有关此选项的任何文档。此外,就像 OP 所说,添加此选项会在运行 rspec 时导致错误。有没有更好的解决方案?
    • @whales 将其修复为之前需要 gem 会使其加载 gem 所需的文件,这些文件恰好是 factory.rb。由于如果工厂文件尝试加载类 Category 并且在加载类时如果需要该表存在,则该表不存在,它将出错。当您运行 rspec 时,您可以先要求它,然后如果表存在,它应该能够正常加载工厂。
    【解决方案2】:

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

    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
    

    如果您有很多工厂,这可能不可行,但相当简单。另见here

    【讨论】:

    • 谢谢,帮我修好了!
    • 我需要这个答案(尽管我还在 factory_girl Gemfile 列表中应用了关于设置 require=false 的建议。)FactoryGirl 在加载环境时尝试在创建表之前创建对象。
    • 这是最终为我解决问题的答案。
    【解决方案3】:

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

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

    上面的 rake db:migrate 在开发环境中运行任何待处理的迁移 并更新db/schema.rbrake 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.
    

    【讨论】:

      【解决方案4】:

      你不应该做任何这些..我认为问题在于你对 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-21
        • 2012-01-18
        • 2020-04-29
        • 2010-10-15
        相关资源
        最近更新 更多