部分测试替身

部分测试替身 是系统中真实对象的扩展,在测试的上下文中被赋予测试替身般的行为。这种技术在 Ruby 中非常常见,因为我们经常看到类对象充当方法的全局命名空间。例如,在 Rails 中

  person = double("person")
  allow(Person).to receive(:find) { person }

在这种情况下,我们对 Person 进行了改造,使其在接收到 `find` 消息时返回我们定义的 Person 对象。我们还可以设置消息期望,这样如果 `find` 没有被调用,示例就会失败。

  person = double("person")
  expect(Person).to receive(:find) { person }

RSpec 将我们正在模拟或存根的方法替换为它自己的测试替身般的机制。在示例结束时,RSpec 会验证所有消息期望,然后恢复原始方法。

注意:我们建议启用 verify_partial_doubles 配置选项。

仅重新定义指定的方法

给定 一个名为“partial_double_spec.rb”的文件,其中包含

RSpec.describe "A partial double" do
  # Note: stubbing a string like this is a terrible idea.
  #       This is just for demonstration purposes.
  let(:string) { "a string" }
  before { allow(string).to receive(:length).and_return(500) }

  it "redefines the specified methods" do
    expect(string.length).to eq(500)
  end

  it "does not effect other methods" do
    expect(string.reverse).to eq("gnirts a")
  end
end

我运行 `rspec partial_double_spec.rb`

那么 示例都应该通过。

示例完成时,原始方法将被恢复

给定 一个名为“partial_double_spec.rb”的文件,其中包含

class User
  def self.find(id)
    :original_return_value
  end
end

RSpec.describe "A partial double" do
  it "redefines a method" do
    allow(User).to receive(:find).and_return(:redefined)
    expect(User.find(3)).to eq(:redefined)
  end

  it "restores the redefined method after the example completes" do
    expect(User.find(3)).to eq(:original_return_value)
  end
end

我运行 `rspec partial_double_spec.rb --order defined`

那么 示例都应该通过。