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

标签 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.

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

最佳答案

Spies are an alternate type of test double that support this pattern by allowing you to expect that a message has been received after the fact, using have_received.

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

只有 spy 对象可以存储方法调用。要按照您想要的方式测试您的真实类,您必须在初始化类之前使用 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

关于ruby - RSpec - 如何测试对象是否在 #initialize 中向自身发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40025889/

相关文章:

testing - 没有使用 Rspec 的请求规范的回溯

mysql - 创建了 <timestamp>_add_devise_to_users.rb 而不是 <timestamp>_devise_create_users.rb

ruby-on-rails - 如何测试 after_sign_in_path_for(resource)?

javascript - 如何在 ReactJS 组件中使用 Ruby 方法?

ruby-on-rails - load 与 Ruby 中的 require 有何不同?

ruby - RSpec 规范没有运行?

ruby-on-rails - 将 capybara 从 1.0.1 升级到 1.1.4 使 database_cleaner 打破了我的规范

ruby-on-rails - 如何为邮件拦截器编写 RSpec?

ruby-on-rails - 寻找更快的 ActiveRecord 查询 (Ruby on Rails)

ruby-on-rails - 如何理解#map方法的核心概念