【问题标题】:Does ActiveRecord make Ruby on Rails code hard to test?ActiveRecord 是否会使 Ruby on Rails 代码难以测试?
【发布时间】:2011-02-09 10:24:45
【问题描述】:

我大部分时间都在使用静态类型语言(主要是 C#)。由于静态方法以及实体和数据访问代码的混合,我对 Active Record 模式和单元测试有一些不好的体验。

由于 Ruby 社区可能是最受测试驱动的社区,而且 Rails ActiveRecord 似乎很受欢迎,因此必须有某种方法在 Ruby on Rails 中结合基于 TDD 和 ActiveRecord 的代码。

我猜想动态语言会以某种方式解决这个问题,但我不知道如何解决。那么,诀窍是什么?

【问题讨论】:

    标签: ruby-on-rails ruby unit-testing activerecord tdd


    【解决方案1】:

    诀窍是您不需要技巧。您可以在测试中创建 ActiveRecord 实例。查看here 了解如何在 Rails 中使用简单测试的一些基本步骤。

    您可以阅读 Rails 官方testing guide 来构建关于 Rails 中的 TDD 的一些想象。还可以看看另外两个流行的测试框架RSpec(我最喜欢,观看mocking screencast)和Shoulda

    【讨论】:

    • 感谢您的链接。那么,让单元测试在 RoR 中访问数据库而不是模拟数据访问似乎是标准做法?如果是这种情况,我可以看出没有问题,因为根据我的经验,ActiveRecord 的问题在于它很难模拟。
    • 不,模拟并不难。并且您在测试期间只点击 TEST 环境数据库(点击时)。但是,当您不想访问数据库时,您不需要访问数据库。
    【解决方案2】:

    问题是固定装置很糟糕。不久前,我读了一篇名为The Lie 的文章,它让我大开眼界。本文重点关注Machinist,我用过也很喜欢,但目前我更喜欢factory_girl。这是他们自述文件中的一个基本示例:

    您定义一个工厂,其默认值刚好足以让您的测试通过:

    # This will guess the User class
    Factory.define :user do |u|
      u.first_name 'John'
      u.last_name  'Doe'
      u.admin false
    end
    

    然后在您的测试中,您可以根据需要覆盖或添加值(人为的 RSpec 示例)

    describe User, "#is_admin?" do
      before(:each) do
        @user = Factory(:user, :admin => true, :email => 'jdoe@email.com')
      end
    
      it "should be true"
        @user.is_admin?.should be_true
      end
    end
    

    @user 现在是一个真实的、活动的、工作的 ActiveRecord 模型,它(临时)存在于测试数据库中。您也可以在控制器测试中使用工厂。您可以嘲笑它们,但以我有限的经验,这种努力不值得微小的性能提升。大多数情况下,我在需要测试条件时进行模拟(save 即使记录有效也会返回 false,以便我可以测试失败的条件)。

    在使用了这里提到的两个库之后,你不能花钱让我再次使用fixtures。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      相关资源
      最近更新 更多