如何让我的Rspec单元测试假装另一个方法的输出是XYZ

如何让我的Rspec单元测试假装另一个方法的输出是XYZ,rspec,mocking,stubbing,Rspec,Mocking,Stubbing,使用Rspec,我正在为@survey.description编写单元测试: class Survey < ActiveRecord::Base def description if self.question.try(:description).present? && self.selected_input.present? return self.question.try(:description).gsub("{{product-name}}"

使用Rspec,我正在为@survey.description编写单元测试:

class Survey < ActiveRecord::Base
  def description
    if self.question.try(:description).present? && self.selected_input.present?
      return self.question.try(:description).gsub("{{product-name}}", self.selected_input.name)
    else
      return self.question.try(:description)
    end
  end    
  def selected_input
    @matches = Input.all.select{|input| self.goods.to_a.matches(input.goods) && self.industries.to_a.matches(input.industries) && self.markets.to_a.matches(input.markets)}
    @selection = @matches.select{|input| input.in_stock(self.competitor) == true}
    if @selection.empty? || @selection.count < self.iteration || @selection[self.iteration-1].try(:name).nil?
      return false
    else
      return @selection[self.iteration-1]
    end
  end    
end

我已经给这篇文章贴上了标签
mocking
stubing
,因为我从来没有有意识地使用过这两种技术,但我认为其中一种可能会找到答案。

一般来说,为测试对象存根方法不是一个好主意。但是,由于您询问了语法,您需要的是:


@史蒂文·诺布尔:这会让你的测试变得脆弱。因为您正在将测试绑定到实现。存根与其他对象的交互是可以的(这是一种基于另一个对象的API的稳定性计算出来的权衡)。您不关心被测试对象如何在内部进行委托,只关心它如何基于输入和输出进行行为。查看Sandi Metz的书“Ruby中的实用面向对象设计”和
describe "description" do
  it "should do something when there is a selected input" do
      just_pretend_that @survey.selected_input = "apples"
      @survey.description.should == "How's them apples?"
  end
end
describe Survey do
  subject(:survey) { Survey.new(...) }

  context 'requesting the description' do
    it 'contains product name when it has input' do
      survey.stub(selected_input: 'apples')
      expect(survey.description).to eq "How's them apples?"
    end
  end
end