【问题标题】:How to write specs for this public method (using RSpec)?如何为这个公共方法编写规范(使用 RSpec)?
【发布时间】:2012-01-04 16:31:38
【问题描述】:

我写了以下课程:

# 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 时,我迷失了方向。有人可以给我一些提示,我可以如何解决为该方法编写规范的问题吗?

【问题讨论】:

  • 这个问题最好在codereview.stackexchange.com结束。
  • @gikian 他的意思是 codereview.stackexchange.com 上的问题会更好,这明确意味着编码风格/完整性的问题。
  • @Dave Newton:从他的最后一个问题(他删除并创建了这个新副本)看来,他似乎不想知道他的规范是否完整,而是他如何真正为get_data 方法。
  • @gikian 您能否添加您正在使用的 Ruby 和 Rspec(可能还有 Rails)的版本?无论问题如何,这类信息几乎总是相关的。

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


【解决方案1】:

一个简单的测试肯定是这样的:

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

一些代码:

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 了解更多信息。

这里的一些 cmets 也是正确的,您可能在某些时候需要模拟,并且您可能确实需要重构此方法,因此发布到代码风格论坛也可能是一个想法。

【讨论】:

  • @lain 您提供的规范涵盖了除私有方法之外的整个类?
  • @gikian 不,它在某些方面部分涵盖了类的公共部分。它不包括无效参数,或者当数据库有错误数据等时。这是给你的。至于测试私有方法,见blog.rubybestpractices.com/posts/gregory/…
  • @lain 你能告诉我应该是_a_kind_of 和应该包括匹配器吗?他们来这里的目的是什么?
  • @lain 还有一件事。您将上下文用于嵌套组......第一个上下文是用于初始化方法,第二个是用于 get_data 方法吗?如何为我的公共方法编写错误的规范...谢谢
  • be_a_kind_of 检查返回值的类型是否符合您的预期。 Ruby 是一种动态语言,你不会总是得到你所期望的,所以检查......它是你期望的 Hash,还是 Array,或其他类型的对象?应该在这里包含示例relishapp.com/rspec/rspec-expectations/v/2-7/docs/…,我会将它用于任何类型的列表/哈希对象。我推断这就是您通过名称 get_data 得到的,但只有您知道。
【解决方案2】:

这很冗长,你这里唯一的实际方法是get_data。你可以使用:

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

免费获取访问器、构造器等,而不是测试它们(参见Struct)

【讨论】:

  • 我怎样才能为这个类写一个正确的规范我没有从我昨天搜索的任何地方得到任何明确的方向但没有成功:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多