RSpec - 如何测试对象是否在#initialize中向self发送消息

时间:2016-10-13 16:03:52

标签: ruby rspec

读完这个问题后,我真的不喜欢这个答案。

Rails / RSpec: How to test #initialize method?

也许我有第三种情况。这就是我现在所拥有的,受到该答案的第二个代码的启发。

# Picture is collection of SinglePictures with same name and filename,
# but different dimensions
class Picture
  attr_accessor :name, :filename
  attr_reader :single_pics, :largest_width

  def initialize(name, filename, dimensions=nil)
    @largest_width = 0
    @single_pics = {}
    add_single_pics(dimensions) if dimensions
  end

  def add_single_pics(max_dimension)
    # logic
  end
end

describe '#initialize' do
  it 'should not call add_single_pics if dimensions is not given' do
    subject = Picture.new('Test Picture', 'Test-Picture')
    expect(subject.largest_width).to eq 0
  end

  it 'should call add_single_pics if dimensions are given' do
    subject = Picture.new('Test Picture', 'Test-Picture', 1920)
    expect(subject.largest_width).to eq 1920
  end
end

我真的不喜欢这样,因为我正在#initialize测试中测试add_single_pics的功能。我想在规范中以某种方式写这个:

  expect(subject).not_to have_received(:add_single_pics)
  expect(subject).to have_received(:add_single_pics)

但是我得到了

Expected to have received add_single_pics, but that object is not a spy
or method has not been stubbed.

我能以某种方式解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

  

间谍是支持这种模式的另一种测试双重类型   允许您期望在收到邮件之后收到邮件   事实上,使用has_received。

https://relishapp.com/rspec/rspec-mocks/v/3-5/docs/basics/spies

只有间谍对象才能存储方法调用。要以您想要的方式测试您的真实课程,您必须在初始化课程之前使用expect_any_instance_of语句:

expect_any_instance_of(Picture).to receive(:add_single_pics)
Picture.new('Test Picture', 'Test-Picture')

在这种情况下,将调用add_single_pics方法,但不会运行其逻辑,如果需要运行它,则需要在匹配器上调用and_call_original方法:

expect_any_instance_of(Picture).to receive(:add_single_pics).and_call_original