【问题标题】:Testing rails STI subclasses with rspec使用 rspec 测试 Rails STI 子类
【发布时间】:2013-01-10 21:09:35
【问题描述】:

给定一个继承自 ActiveRecord::Base 的类,我们称它为 Task,我有两个子类专门用于任务的某些方面,Activity 和 Training,使用标准 Rails 单表继承。

在查看其他可用数据后,我对这个选择充满信心,因为模型的实际数据是相同的,只是行为不同。非常适合 STI。

可以创建、启动、推进和完成任务。这是这些转换中涉及的一些逻辑,尤其是start(),需要对基类进行专门化。

由于我正在执行此 TDD 并开始使用具有完整测试覆盖率的工作任务调用,我现在想知道如何继续。我有几个我想过的情景:

  1. 复制 Task 的测试并端到端测试 Activity 和 Training 并进行一些小的修改以测试它们的专业化。优点:快速简单。缺点:它会重复代码,虽然这可能不是什么大问题,但当专业化数量增加时。

  2. 拆分测试并将大部分测试代码保存在task_spec.rb 中,同时将专业化测试移至各个子类的新规范中。优点:保持测试干燥。缺点:我在基础测试中实例化什么类?

最后一个问题困扰着我。现在我已经设置了基类测试,可以从一个 Concert 子类中随机创建一个类,但这是一种好的形式吗?这几乎让我想采用方法 1 只是为了保持测试运行的一致性,否则我将不得不找到一种方法来确定我的类选择随机种子的随机性,以便我至少有一个可重复的随机选择。

我猜这一定是人们遇到的常见问题,但我找不到任何关于该主题的好信息。您对此事有任何资源或想法吗?

【问题讨论】:

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


    【解决方案1】:

    使用 rspec 共享示例(Renato Zannon 提到)如下所示:

    spec/support/ 中创建一个文件。我就叫它shared_examples_for_sti.rb

    require 'spec_helper'
    
    shared_examples "an STI class" do
    
      it "should have attribute type" do
        expect(subject).to have_attribute :type
      end
    
      it "should initialize successfully as an instance of the described class" do
        expect(subject).to be_a_kind_of described_class
      end
    
    end
    

    在每个 STI 类及其子类的 _spec.rb 文件中,添加以下行:

    it_behaves_like "an STI class"
    

    如果您想在 STI 类和子类之间共享任何其他测试,只需将它们添加到 shared_examples

    【讨论】:

      【解决方案2】:

      您可以使用rspec shared examples 来测试它们之间共享的行为(基本上是继承的行为,或者您要防范LSP 违规的地方)。

      【讨论】:

      • 既然您指出了这一点,这似乎很明显:) 我在测试中尝试了这种方法,它非常适合。我知道必须有一种简单的方法来做到这一点,毕竟这一定是一个普遍的要求。谢谢你的指点,它帮助我提高了我的 TDD 技能。
      • 我很高兴它有帮助:) 也许你应该考虑阅读POODR 这本书。它讨论了许多通过继承和组合重用代码的技术。
      • 我在第 7 章...所以我很快就会进入测试部分:)
      猜你喜欢
      • 1970-01-01
      • 2016-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多