【问题标题】:Cleanly Setting up multiple models in FactoryGirl for a test/spec在 FactoryGirl 中干净地设置多个模型以进行测试/规范
【发布时间】:2013-05-07 15:04:01
【问题描述】:

我一直在学习 Rails 最佳实践并学习为我的 Rails 应用程序编写好的测试。

我目前正在使用 rspec + FactoryGirl 进行测试。

有一段时间我在编写基本模型和控制器规范,通常只需要设置几个模型和关联。

现在我有一个具有复杂算法的模型,该模型基于不同的模型进行大量计算。

为了测试这种方法,我几乎需要我的应用程序的所有模型都存在于测试数据库中,并且它们之间建立了所有关联关系。

现在事情变得势不可挡。我需要跟踪所有工厂是否正确地相互引用。我还需要验证是否所有工厂都已正确创建。 在我的 before(:each) 方法中还有很多 FactoryGirl.create(:model) 调用。

我有一种感觉,我做的事情不对。解决这种情况的最佳方法是什么?大多数书籍和示例仅涵盖非常基本的案例。

欢迎任何指针的想法和方法。(希望这个问题的范围不要太宽)

示例:

我的应用程序有多个projects。每个项目有_many indexescompaniesmastertags。每个公司都有_manychannels。每个频道都有多个channel_tag_weights 跨越不同的mastertags。每个频道也有_many Rawdatas

这可能是所需的最低模型设置示例。

【问题讨论】:

  • 一些示例代码会有所帮助
  • 更新了一般场景。
  • 您可以生成辅助方法,在其中分离您的工厂女孩​​代码,例如 def generate_project_with_indexes ... end def generate_project_with_companies .. end 等等。通过这个你最小化你的代码..但是如果你的应用程序增长,你的测试代码也会增长,这是正常的。所以你没有做错事

标签: ruby-on-rails unit-testing rspec factory-bot


【解决方案1】:

我为此编写了一个名为 stepford 的 gem。

在您的 gemfile 中:

group :test do
  gem 'stepford'
  #...
end

然后bundle install

备份您的 factory.rb 或现有的多个包含工厂的文件。事实上,您需要将它们移开,因为如果它加载其他工厂,可能会干扰。

然后:bundle exec stepford factories --path spec(如果想将 factory.rb 放在规范目录中 - 还有其他选项可以为每个模型创建一个工厂,等等)。

我们遇到了需要在存在外键约束的情况下创建依赖项的问题。在此过程中,我编写了modelist gem,它可以帮助识别循环依赖关系,如果您使用的是遗留数据,您可能需要检查并运行它。而 Stepford 的深度创作方法则绕过了这些问题。但是,我们已经开始避免使用 Stepford 的 deep_* 方法,尽管我们仍然使用了一点。最好具体说明您在做什么并直接使用 factory girl,即使它会使测试代码更脆弱且看起来过于复杂。

您也可以查看灯具,或machinist。这真的取决于你需要什么。

如果您需要实际为模型创建所有代码,那就是另外一个问题了。我编写了一个脚本来为本地遗留模式(非常大)生成模型,它确实有帮助,但需要几个月的迭代工作。问题是模式本身不是(必然)模型中关联或设置的明确描述。为了让您了解我在说什么,我写了一些 gem 来帮助遗留应用程序等正在做/已经做过的一些我们必须处理的事情,比如不可删除、activerecord-define_nils、 mark_only、activerecord-custom_timestamps、activerecord-native_db_types_override 以及早期尝试中的其他一些。我们使用了一些已经存在的很棒的 gem,比如 composite_primary_keys 和 foreigner。

我们努力解决的其他一些问题是使用 MTI(多表继承),尽管有一些宝石试图提供帮助,但我们最终通过钩子等在我们的模型中自己处理它。我们合并了一些模式(不能掉以轻心,但分区不是必需的,并且 apartment、second_base 和类似的 gem 会增加复杂性,甚至不考虑无法加入,使用普通查询)。

请注意:在我们的例子中,我们有很多桌子。如果你没有那么多,你仍然可以使用 Stepford 来让第一次创建工厂更容易一些,但我认为你会没事的。

【讨论】:

  • @Myth17 你在使用 Mongoid?抱歉,您没有在原始问题中指定。 :( 假设由于我正在做的一些事情它不起作用,所以请在github.com/garysweaver/stepford/issues 中打开一个问题并查看它。欢迎 PR。(它也需要清理,也许使用 Eager加载与路径相关的模型文件加载、更多测试等)
  • 谢谢@GaryS.Weaver 我很快就会试一试! :)
【解决方案2】:

每当我遇到这种情况时,我都会尝试确保我的所有 FactoryGirl 模型都利用 FactoryGirl 的内置关联方法:

https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations

这样,为了使单个模型正确验证所需的关联模型就会出现。 FactoryGirl 将完成使用额外测试数据填充数据库的过程。

因为您正在使用 has_many 关联,所以您需要研究工厂定义的 after(:create) 方法以正确设置关联。这也将允许您创建特定于这些深度集成规范的定义,并使更简单的工厂独立于更简单的规范。

【讨论】:

    【解决方案3】:

    如果您只测试一种方法,那就是单元测试。

    我认为你不需要设置太多东西。

    一个方法具有输入和输出,您只需将手动创建的输入示例提供给它,并期望它生成正确的输出。

    如果一个方法需要关心的事情太多,你可以将它拆分成几个方法,并对每个方法进行单元测试。

    在进行集成测试时,应该设置整个环境。是的,您需要准备所有需要的工厂。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      相关资源
      最近更新 更多