ruby - 使用 RSpec 进行问题 stub

标签 ruby rspec stub

我试图理解为什么这些测试的结果,第一个测试声称该方法没有 stub ,但是第二个是。

class Roll
  def initialize
    install if !installed?
  end
  def install; puts 'install'; end
end

describe Roll do
  before do
    class RollTestClass < Roll; end
    RollTestClass.any_instance.stub(:install)
  end

  let(:roll_class) { RollTestClass }
  let(:roll) { RollTestClass.new }

  context 'when installed is true' do
    before do
      roll_class.any_instance.stub(:installed?).and_return(true)
    end

    it 'should not call install' do
      expect(roll).to_not have_received(:install)
    end
  end

  context 'when installed is false' do
    before do
      roll_class.any_instance.stub(:installed?).and_return(false)
    end

    it 'should call install' do
      expect(roll).to have_received(:install)
    end
  end
end

错误说 expected to have received install 也很奇怪,但我认为这可能只是来自 RSpec DSL 的错误反馈。但也许值得注意。

  1) Roll when installed is true should not call install
     Failure/Error: expect(roll).to_not have_received(:install)
       #<RollTestClass:0x10f69ef78> expected to have received install, but that method has not been stubbed.

最佳答案

RSpec 的“ spy 模式”要求对象之前已经 stub 。但是,any_instance.stub 实际上并不“真实地” stub 方法,除非/直到在特定对象上调用该方法。因此,这些方法显示为“未 stub ”并且您得到了您遇到的错误。下面是一些演示定义更改的代码:

class Foo
end

describe "" do
  it "" do
    Foo.any_instance.stub(:bar)
    foo1 = Foo.new
    foo2 = Foo.new
    print_bars = -> (context) {puts "#{context}, foo1#bar is #{foo1.method(:bar)}, foo2#bar is #{foo2.method(:bar)}"}
    print_bars['before call']
    foo1.bar
    print_bars['after call']
  end
end

产生以下输出:

before call, foo1#bar is #<Method: Foo#bar>, foo2#bar is #<Method: Foo#bar>
after call, foo1#bar is #<Method: #<Foo:0x007fc0c3842ef8>.bar>, foo2#bar is #<Method: Foo#bar>

我在 RSpec 的 github 站点上报告了这个问题并得到了 this acknowledgement/response .

可以使用以下替代方法,这取决于最近引入的expect_any_instance_of 方法。

class Roll
  def initialize
    install if !installed?
  end
  def install; puts 'install'; end
end

describe Roll do
  before do
    class RollTestClass < Roll; end
  end

  let(:roll_class) { RollTestClass }
  let(:roll) { RollTestClass.new }

  context 'when installed is true' do
    before do
      roll_class.any_instance.stub(:installed?).and_return(true)
    end

    it 'should not call install' do
      expect_any_instance_of(roll_class).to_not receive(:install)
      roll
    end
  end

  context 'when installed is false' do
    before do
      roll_class.any_instance.stub(:installed?).and_return(false)
    end

    it 'should call install' do
      expect_any_instance_of(roll_class).to receive(:install)
      roll
    end
  end
end

关于ruby - 使用 RSpec 进行问题 stub ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20152470/

相关文章:

ruby - 重命名模型后更新回形针文件名?

ruby - 使用 method_added 获得一个无限循环并一起初始化

ruby - 如何卸载旧版本的 Ruby,这是明智之举吗?

ruby - rspec/serverspec 服务测试总是失败

ruby rspec 错误“预期 : 1 got: #<Proc:0x000000019155b8@/home

sql - MySQL 或 Rails 中在特定日期范围内每天获取 AVG 的最佳方法

ruby-on-rails-3 - Capybara::FrozenInTime 使用 Rspec + Timecop + Capybara + Capybara Webkit 的集成规范中的错误

ruby-on-rails - 在 rspec 特性测试中使用 Devise

java - 如何创建 stub ?

java - Mockito 中的可选 stub