使用rspec测试rails STI子类

时间:2013-01-27 10:52:05

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

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

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

可以创建,启动,进行和完成任务。这是这些转换中涉及的一些逻辑,特别是start(),它要求基类的专门化。

由于我正在做这个TDD,并开始使用完整测试覆盖的工作任务调用,我现在想知道如何继续。我有一些我想过的情景:

  1. 复制Task的测试并通过一些小的修改来端到端地测试Activity和Training,以测试它们的专业化。亲:这很快捷。 Con:它复制代码,虽然这可能不是一个大问题,但是当专业化数量增加时。

  2. 拆分测试并将大部分测试代码保留在task_spec.rb中,同时将专业化测试移动到相应子类的新规范中。 Pro:保持测试干燥。 Con:我在基础测试中实例化哪个类?

  3. 最后一个问题是什么在唠叨我。现在我已经设置了基类测试来从一个音乐会子类中随机创建一个类,但这是一个好的形式吗?它几乎让我想要采用方法1只是为了保持测试运行一致或者我必须找到一种方法来为测试套件选择随机种子的类随机性,这样我至少可以重复随机选择。

    我猜这一定是人们遇到的常见问题,但我找不到关于这个主题的任何好消息。你对这件事有什么资源或想法吗?

2 个答案:

答案 0 :(得分:10)

使用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

答案 1 :(得分:4)

您可以使用rspec shared examples来测试所有这些行为共享的行为(基本上是继承的行为,或者您希望防范LSP违规行为的地方)。