如何为这个公共方法编写规范(使用RSpec)?

时间:2012-01-04 16:31:38

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

我写了以下课程:

# This class is responsible for getting the data to create the sitemap
class City
  attr_accessor :country_version, :directory, :country_host, :locale

  def initialize(country_version, directory, country_host,locale)
    @country_version = country_version
    @directory = directory
    @country_host = country_host
    @locale = locale
  end

  def get_data
    ::City.find_each(:conditions => {:country_version_id => @country_version.id}) do |city|
      I18n.locale=(@locale)
      yield entry(city)
    end
  end

  private

  def entry(city)
    {
      :loc => ActionController::Integration::Session.new.url_for(
                  :controller => 'cities', 
                  :action => 'show', 
                  :city_name => city.name, 
                  :host => @country_host.value),
      :changefreq => 0.8,
      :priority => 'monthly',
      :lastmod => city.updated_at
    }
  end
end 

我正在使用RSpec为这个类编写规范。到目前为止,我的规范涵盖了访问器方法和构造函数。然而,当谈到更复杂的方法get_data时,我迷失了。有人能给我一些提示,我可以解决为该方法编写规范的问题吗?

2 个答案:

答案 0 :(得分:2)

一个简单的测试肯定会遵循:

  • 实例化会不会爆炸?
  • 如果给出好的参数,它会返回数据吗?
  • 当给出错误的参数或导致没有结果的参数时,它是否会返回我期望的(零/零/异常?)?

一些代码:

describe :City do
  let(:country_version) { 123412 }
  # other useful args here
  context "On instantiation" do
    context "Given valid arguments" do
      subject { City.new country_version, ...}
      it { should_not be_nil }
      it { should be_a_kind_of City }
    end
  end
  end
  context "Given a country version id" do
    context "that is valid" do
      context "and records exist for in the datastore"
        let(:city) { City.new country_version, ...}
        subject { city.get_data }
        it { should_not be_nil } 
        it { should be_a_kind_of... (Array, Hash?) }
        it { should include( ...? }
      end
    end
  end
end

显然,这不会起作用,因为我不知道应该进出什么,但是它会给你一些东西,它也暗示了一些缺失的规范(比如无效的参数等等)等)

有关详情,请参阅https://www.relishapp.com/rspec/rspec-expectations

这里的一些评论也是正确的,你可能在某些时候需要模拟,你可能还需要重构这个方法,所以发布到代码风格论坛也可能是一个想法。

答案 1 :(得分:0)

这是非常详细的,这里唯一的实际方法是get_data。你可以使用:

class City < Struct(:country_version, :directory, :country_host, :locale)
  ...
end

要免费获取访问者,构造函数和更多内容,而不是测试它们(请参阅Struct