包装原始实现

使用 and_wrap_original 修改部分替身的原始响应。当你想利用外部对象但要修改其响应时,这很有用。例如,如果 API 返回大量数据,出于测试目的,你希望将其裁剪。你也可以用它来配置大多数参数的默认响应,然后使用 with 为特定参数覆盖默认响应。

注意:and_wrap_original 仅支持部分替身,因为普通测试替身没有原始实现。

背景

假设有一个名为“lib/api.rb”的文件,内容如下

class API
  def self.solve_for(x)
    (1..x).to_a
  end
end

and_wrap_original 包装了原始部分替身响应

假设有一个名为“spec/andwraporiginal_spec.rb”的文件,内容如下

require 'api'

RSpec.describe "and_wrap_original" do
  it "responds as it normally would, modified by the block" do
    expect(API).to receive(:solve_for).and_wrap_original { |m, *args| m.call(*args).first(5) }
    expect(API.solve_for(100)).to eq [1,2,3,4,5]
  end
end

我运行 rspec spec/and_wrap_original_spec.rb

那么这些示例应该全部通过。

and_wrap_original 可以配置一个可以为特定参数覆盖的默认响应

假设有一个名为“spec/andwraporiginal_spec.rb”的文件,内容如下

require 'api'

RSpec.describe "and_wrap_original" do
  it "can be overridden for specific arguments using #with" do
    allow(API).to receive(:solve_for).and_wrap_original { |m, *args| m.call(*args).first(5) }
    allow(API).to receive(:solve_for).with(2).and_return([3])

    expect(API.solve_for(20)).to eq [1,2,3,4,5]
    expect(API.solve_for(2)).to eq [3]
  end
end

我运行 rspec spec/and_wrap_original_spec.rb

那么这些示例应该全部通过。

and_wrap_original 可以配置一个可以为特定关键字参数覆盖的默认响应

假设有一个名为“lib/kw_api.rb”的文件,内容如下

class API
  def self.solve_for(x: 1, y: 2)
    (x..y).to_a
  end
end

假设有一个名为“spec/andwraporiginal_spec.rb”的文件,内容如下

require 'kw_api'

RSpec.describe "and_wrap_original" do
  it "can be overridden for specific arguments using #with" do
    allow(API).to receive(:solve_for).and_wrap_original { |m, **kwargs| m.call(**kwargs).first(5) }
    allow(API).to receive(:solve_for).with(x: 3, y: 4).and_return([3])

    expect(API.solve_for(x: 1, y: 20)).to eq [1,2,3,4,5]
    expect(API.solve_for(y: 20)).to eq [1,2,3,4,5]
    expect(API.solve_for(x: 3, y: 4)).to eq [3]
  end
end

我运行 rspec spec/and_wrap_original_spec.rb

那么这些示例应该全部通过。