使用实例替身

一个 instance_double 是最常见的验证替身类型。它接受一个类名或对象作为第一个参数,然后验证任何正在被模拟的方法都应该存在于该类的实例上。此外,当它接收消息时,它会验证提供的参数是否被方法签名支持,包括参数数量和允许或必需的关键字参数(如果有)。当您限制参数使用 with 时,也会进行相同的参数验证。

对于由 method_missing 处理的方法,请参阅动态类

背景

给定一个名为“app/models/user.rb”的文件,内容如下:

class User < Struct.new(:notifier)
  def suspend!
    notifier.notify("suspended as")
  end
end

给定一个名为“spec/unit_helper.rb”的文件,内容如下:

$LOAD_PATH.unshift("app/models")

给定一个名为“spec/spec_helper.rb”的文件,内容如下:

require 'unit_helper'

require 'user'
require 'console_notifier'

RSpec.configure do |config|
  config.mock_with :rspec do |mocks|

    # This option should be set when all dependencies are being loaded
    # before a spec run, as is the case in a typical spec helper. It will
    # cause any verifying double instantiation for a class that does not
    # exist to raise, protecting against incorrectly spelt names.
    mocks.verify_doubled_constant_names = true

  end
end

给定一个名为“spec/unit/user_spec.rb”的文件,内容如下:

require 'unit_helper'

require 'user'

RSpec.describe User, '#suspend!' do
  it 'notifies the console' do
    notifier = instance_double("ConsoleNotifier")

    expect(notifier).to receive(:notify).with("suspended as")

    user = User.new(notifier)
    user.suspend!
  end
end

在隔离情况下,规范通过

我运行 rspec spec/unit/user_spec.rb

那么所有示例都应该通过。

规范在加载依赖项和实现方法的情况下通过

给定一个名为“app/models/console_notifier.rb”的文件,内容如下:

class ConsoleNotifier
  def notify(msg)
    puts message
  end
end

我运行 rspec -r./spec/spec_helper spec/unit/user_spec.rb

那么所有示例都应该通过。

规范在加载依赖项和未实现方法的情况下失败

给定一个名为“app/models/console_notifier.rb”的文件,内容如下:

class ConsoleNotifier
end

我运行 rspec -r./spec/spec_helper spec/unit/user_spec.rb

那么输出应该包含“1 个示例,1 个失败”。

并且输出应该包含“ConsoleNotifier 类未实现实例方法:”。

规范在加载依赖项和参数数量不正确的情况下失败

给定一个名为“app/models/console_notifier.rb”的文件,内容如下:

class ConsoleNotifier
  def notify(msg, color)
    puts color + message
  end
end

我运行 rspec -r./spec/spec_helper spec/unit/user_spec.rb

那么输出应该包含“1 个示例,1 个失败”。

并且输出应该包含“参数数量错误”。