ruby - 如何对严重依赖于其他类的类进行单元测试?

标签 ruby unit-testing rspec

我的理解是单元测试应该单独测试类,关注细粒度行为并尽可能使用 double /模拟替换其他类的对象。 (如果我在这里错了,请纠正我。)

我正在编写一个带有名为 MatchList 的类的 gem。 MatchList::new 有两个参数,每个参数都是另一个名为 MatchPhrase 的类的实例。 MatchPhrase 包含一些 MatchList 严重依赖的行为(即, 如果您将 MatchPhrase 以外的任何内容提供给 MatchList::new,你会得到一堆“未定义的方法”错误)。

我当前的(幼稚的?)测试设置使用 let 语句来分配变量以供我的示例使用:

let(:query)      { MatchPhrase.new('Good Eats') }
let(:candidate)  { MatchPhrase.new('Good Grief') }
let(:match_list) { MatchList.new(query, candidate) }

我该如何编写这个单元测试?我是否认为应该在不调用 MatchPhrase 类的情况下完成?这可能吗?


作为引用,下面是 MatchList 类的样子:

class MatchList < Array
  attr_reader :query, :this_phrase, :that_phrase

  def initialize(query, candidate)
    super(query.length)
    @query = query
    @this_phrase = query.dup
    @that_phrase = candidate
    find_matches until none?(&:nil?)
  end

  private

  def find_matches
    query.each.with_index do |this_token, i|
      next unless self[i].nil?
      that_token = this_token.best_match_in(that_phrase)
      next if that_token.match?(that_token) &&
              this_token != that_token.best_match_in(this_phrase)
      self[i] = this_token.match?(that_token) ? that_token : NilToken.new
      this_phrase.delete_once(this_token)
      that_phrase.delete_once(that_token)
    end
  end
end

最佳答案

My understanding is that unit testing should test classes in isolation, focusing on granular behavior and substituting objects of other classes using doubles/mocks wherever possible. (Please correct me if I'm wrong here.)

根据我的理解,这是不正确的。 使用 double /模拟有优点也有缺点。

优点是您可以使用数据库、电子邮件等慢速服务并使用快速执行的对象模拟它。

缺点是您模拟的对象不是“真实的”对象,可能会让您感到惊讶并且行为与真实对象不同。

这就是为什么在可行的情况下最好使用真实的对象。 仅当您想加快测试速度或导致更简单的测试时才使用模拟。即使这样,也可以使用真实对象进行一项测试来验证它是否一切正常。这称为集成测试。

考虑到您的情况:

let(:query)      { MatchPhrase.new('Good Eats') }
let(:candidate)  { MatchPhrase.new('Good Grief') }
let(:match_list) { MatchList.new(query, candidate) }

mock query 或 candidate 确实没有优势。

关于ruby - 如何对严重依赖于其他类的类进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42064022/

相关文章:

ruby-on-rails - 为什么不能给这个继承的类属性赋值呢?

ruby-on-rails - Ruby on Rails - 事件记录迁移问题

python - 工厂男孩 - 如何创建工厂所需的数据(预生成 Hook )

ruby-on-rails - 在 rails 中使用 rspec 测试标题

ruby-on-rails-3 - 加快 RSpec 和 Factory girl 模型测试?

html - Ruby On Rails Bootstrap 字形图标无法正常工作

ruby - 输出到控制台,同时在 ruby​​ 中保留用户输入

C 函数调用和参数跟踪 - 测试用例和模拟生成

c# - 如何使用 AutoFixture 生成编译时未知的任意类型的 stub 对象

ruby - 自动测试、RSpec 2 和 Ruby 1.9.2-p0 - 完全没有输出