我在单元测试中滥用存根吗?

时间:2014-02-27 17:04:17

标签: ruby unit-testing tdd stubbing

我正在开发Ruby on Rails应用程序,我有一个BillingPlan模型,其中包含以下方法:

class BillingPlan < ActiveRecord::Base
  # ...

  def billing_months
    dates = [Date.new(Date.today.year, start_month.value, billing_day)]

    while dates.size < billings_in_year
      dates << dates.last + recurrence.value.months
    end

    dates.map{ |d| d.month }
  end

  def billings_in_year
    12 / recurrence.value
  end
end

为了测试代码,我编写了以下规范:

describe BillingPlan do
  # ...

  describe '#billings_in_year' do
    subject do
      (plan = BillingPlan.new).stubs(
        recurrence: stub(value: 4)
      ) && plan
    end

    it 'returns the number of billings in a year' do
      expect(subject.billings_in_year).to eq(3)
    end
  end

  describe '#billing_months' do
    subject do
      (plan = BillingPlan.new).stubs(
        recurrence: stub(value: 2),
        start_month: stub(value: 2),
        billings_in_year: 6,
        billing_day: 21
      ) && plan
    end

    it 'returns the months when billing is done' do
      expect(subject.billing_months).to eq([2, 4, 6, 8, 10, 12])
    end
  end
end

正如您所看到的,我已经设法通过使用Mocha完全隔离这两种方法。但是,我想知道我在测试中是否滥用存根?是不是太依赖于方法的内部运作?你能否提供一般规则来了解一个人应该依赖嘲弄/伪装的广泛程度?

注意:recurrencestart_month是第三方类的对象。

1 个答案:

答案 0 :(得分:2)

你的测试存根他们需要隔离他们测试的案例,但他们确实暗示你的方法有问题 - 他们不遵守Law of Demeter

  
      
  • 你可以自己玩。
  •   
  • 您可以玩自己的玩具(但不能将它们分开),
  •   
  • 你可以玩给你的玩具。
  •   
  • 你可以玩自己制作的玩具。
  •   

存根存根值所需的每个地方 - 你都有问题。

  

假设这是一个Rails程序,更改它非常容易   代码满足法律。首先,我们对它进行了单行添加   用户类:

class User
  delegate :name, :to => :department, :prefix => true, :allow_nil => true
  # ...
end

如果此解决方案由于某种原因不可行,您可以使用此解决方案:

  

Demeter不会阻止我们与物体互动 -   和三阶联想;它只是声称我们无法互动   与所有这些对象在同一方法中。再看看   法律的制定:

     
    

... M向其发送消息的所有对象......

  
     

Demeter只是关于方法的规则;它不限制集合   类可以与类进行交互。

     

所以这是完全合法的:

class StatPresenter
  def human_stats(human)
    "Age: #{human.age}.nCountry stats:n#{country_stats(human.country)}"
  end

  def country_stats(country)
    "  Mortality rate: #{country.mortality_rate}"
  end
end