1

首先让我承认我通常是一名 Java 程序员,但我正在努力学习 ruby​​。

我正在使用 Ruby 1.9.3 并安装了 test-unit gem(我不知道如何使用 minitest 创建测试套件)。

我有两个类(称它们为 A 和 B),它们旨在支持相同的 API,但是,它们由不同的数据存储支持(为了论证,文件系统与数据库)。

由于它们支持相同的 API,我想编写一个测试集合,但让该集合同时针对 A 类和 B 类运行。

在 Java 中,我将创建三个测试类:

  • AbstractTest :它将列出所有测试方法,并有一个抽象方法 getTestee() ,其实现预计将返回类 A 或类 B 的实例。每个测试方法都将调用 getTestee() 然后执行其测试返回的对象。

  • ATest :它将扩展 AbstractTest,并实现 getTestee() 返回类 A 的实例。

  • BTest :它将扩展 AbstractTest,并实现 getTestee() 返回类 B 的实例。

然而,当我在 ruby​​ 中构建类似的测试类层次结构时,测试框架似乎创建了 AbstractTest 的实例,而不是 ATest 或 BTest。AbstractTest 没有定义 getTestee() 所以我得到一个

NoMethodError: undefined method `getTestee' for test_list(AbstractTest):AbstractTest

无论如何,我的一位同事建议了一个策略,我似乎重新定义了 AbstractTest 类并在事后添加 getTestee 方法。就像是:

require 'tests/abstract_test'

require 'a'

class AbstractTest
  def getTestee
    A.new
  end
end

require 'tests/abstract_test'

require 'b'

class AbstractTest
  def getTestee
    B.new
  end
end

但这真的让我很困惑,看起来像是一种代码味道。感觉就像我现在拥有三个不同的 AbstractTest 类,并且无法在 TestSuite 中单独引用它们。

那么,对于这种情况,ruby 普遍接受的测试实践是什么?

彼得。

4

1 回答 1

2

What I would do is create a base module with all the tests you want to run, and then initialize the objects in your derived classes. Something like this (using Ruby's built-in Test::Unit library):

module Testers
  def test_something
    assert_equal "expected result", @myobject.function_call
  end

  # ....
end

Then later on your actual test classes:

require 'test/unit'

class TestA < Test::Unit::TestCase
  def setup
    @myobject = A.new
  end

  include Testers
end

class TestB < Test::Unit::TestCase
  def setup
    @myobject = B.new
  end

  include Testers
end

The magic here is that using a mixin (combination of a module and include) you can have some of the nice aspects of multiple inheritance without actually having multiple inheritance.

于 2012-07-03T19:01:47.170 回答