RSpec的新手,被新的3.x语法和存根混淆

时间:2015-02-12 18:53:04

标签: ruby rspec stubbing rspec3

我正在努力学习如何使用RSpec,主题的复杂性加上质量教程的普遍缺乏以及最近的重大语法改革让我彻底难过。我想我需要写一个存根(实际上甚至不确定),但我无法弄清楚如何。

正在测试的程序:

Class Session
  def initialize
    @interface = Interface.new
    @high_score = 1
    play
  end

  private
  def play
    get_high_score
  end

  def get_high_score
    score = @interface.get_high_score
    set_high_score(score)
  end

  def set_high_score
    high_score = (score.to_f/2).ceil
    @high_score = high_score
  end
end

class Interface
  def get_high_score
    puts "Best out of how many?"
    high_score = gets.chomp        
  end
end

适用的测试:

describe Session do
  describe "#new" do
    it "gets a high score" do
      session = Session.new
      session.set_high_score(3)
      expect(session.high_score).to eql(2)
    end
  end
end

这显然不起作用,因为它是一种私有方法。期望是它需要提供set_high_score接收3作为其参数,但我不知道如何从公共初始化到设置它。我想我需要写一个存根,但我无法弄清楚它是如何工作的......它也可能是一些其他更普遍的失礼......不确定。我希望有人可以向我解释这些内容。

1 个答案:

答案 0 :(得分:0)

你基本上需要存根你的输入 - 也就是你的获取。在使用之前,您无法获得Interface实例的句柄,并且由于您没有提供注入Interface依赖项的方法,因此您可以使用RSpec的any_instance期望模拟来自Interface对象的响应。

作为一个注释,在Ruby中,您通常会避免使用get_xset_x访问者和获取者,而使用xx=方法。

class Session
  def initialize(interface = nil)
    @interface = Interface.new
    @high_score = 1
    play
  end

  private
  def play
    high_score
  end

  def high_score
    self.high_score = @interface.get_high_score
  end

  def high_score=(score)
    @high_score = (score / 2.0).ceil
  end
end

class Interface
  def get_high_score
    puts "Best out of how many?"
    gets.chomp.to_i
  end
end

describe Session do
  subject { Session.new }
  describe "#new" do
    it "gets a high score" do
      expect_any_instance_of(Interface).to receive(:get_high_score).and_return(3)
      expect(subject.high_score).to eql(2)
    end
  end
end