【问题标题】:Double received unexpected message despite of stubbing尽管存在存根,双重仍收到意外消息
【发布时间】:2014-12-30 03:05:56
【问题描述】:

Double received unexpected message 尝试运行以下规范时报告失败/错误:

MyKlass
  does something
  does something again (FAILED - 1)

Failures:

  1) MyKlass does something again
     Failure/Error: MyKlass.do_something
       Double "OtherKlass" received unexpected message :closed? with (no args)
     # ./lib/my_klass.rb:5:in `do_something'
     # ./spec/my_klass_spec.rb:17:in `block (2 levels) in <top (required)>'

Finished in 2.05 seconds
2 examples, 1 failure

Failed examples:

rspec ./spec/my_klass_spec.rb:16 # MyKlass does something again

这是一个简单的示例,可以轻松重现此问题...

规格文件spec/my_klass_spec.rb:

 1 require "spec_helper"
 2
 3 class OtherKlass; end
 4 
 5 describe MyKlass do
 6   let(:objekt) { double("OtherKlass", closed?: "NOT REALLY") }
 7 
 8   before :each do
 9     OtherKlass.stub(:get_objekt).and_return(objekt)
10   end
11 
12   it "does something" do
13     MyKlass.do_something
14   end
15 
16   it "does something again" do
17     MyKlass.do_something
18     MyKlass.do_something
19   end
20 end

还有代码lib/my_klass.rb

1 class MyKlass
2   @@klass_var = nil
3 
4   def self.do_something
5     if @@klass_var.blank? || @@klass_var.closed?
6       @@klass_var ||= OtherKlass.get_objekt
7     end
8   end
9 end

我不明白为什么closed? 被报告为意外消息,当它在我的规范文件的第 6 行存根时。

非常感谢您的帮助!

【问题讨论】:

  • 你看过吉姆的回答了吗?我不认为你可以在类方法上使用 double - stackoverflow.com/a/15252724/3109182
  • 您使用的是哪个版本的 rspec 和 ruby​​?
  • Rails 4.1.6 和 Rspec 2.14.1。

标签: ruby-on-rails ruby rspec rspec-rails


【解决方案1】:

在 RSpec 3 中,您可以使用class_double,它允许您创建一个类的双精度。结合as_stubbed_const,可以替换原来的一个类的实现:

RSpec.describe MyKlass do
  let(:objekt) do
    double(OtherKlass, closed?: 'NOT REALLY')
  end

  before do
    class_double(OtherKlass, get_objekt: objekt).as_stubbed_const
  end

  it 'does something' do
    MyKlass.do_something
  end
end

在 Rspec 2 中,以下应该可以工作:

RSpec.describe MyKlass do
  let(:objekt) do
    double('OtherKlass', closed?: 'NOT REALLY')
  end

  before do
    fake_klass = Class.new
    fake_klass.stub(:get_objekt) { objekt }
    stub_const('OtherKlass', fake_klass)
  end

  it 'does something' do
    MyKlass.do_something
  end
end

【讨论】:

  • 不,它不起作用。报告以下NameErrorundefined local variable or method 'objekt' for #&lt;Class:0x007fc66ea96028&gt;
  • 抱歉,请再次查看
  • 不,抱歉,仍然没有变化。收到与以前相同的错误消息:Double "OtherKlass" received unexpected message :closed? with (no args).
  • 这对我有帮助。在每次测试之前显式设置类变量可以解决问题:before(:each) { MyKlass.class_variable_set :@@klass_var, nil }
【解决方案2】:

在每次测试解决问题之前显式设置一个类变量:

before(:each) do
  MyKlass.class_variable_set :@@klass_var, nil
end

也许有人能找到更好的解决方案,但是这个对我有用。

【讨论】:

    猜你喜欢
    • 2013-04-08
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多