RSpec 的新手,对新的 3.x 语法和存根感到困惑

New to RSpec, confused by new 3.x syntax and stubs

我正在努力学习如何使用 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 作为其参数,但我不知道如何从 public 初始化到设置它。我想我需要写一个存根,但我不知道它到底是如何工作的……也可能是其他一些更普遍的失礼……不确定。我希望有人能给我解释一下。

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

请注意,在 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