Rails rspec undefined方法`receive'用于#<rspec :: examplegroups ::

时间:2018-04-30 17:22:30

标签: ruby-on-rails ruby rspec mocha

=“”

我想测试一些实例没有接收到特定的方法调用。试图

RSpec.describe 'something' do
  before { subject.stubs(foo: 'bar') }
  it { is_expected.to_not receive(:foo) }
end

给了我

Failure/Error: it { is_expected.to_not receive(:foo) }

NoMethodError:
  undefined method `receive' for #<RSpec::ExampleGroups::Something:0x0000000010391588>

并尝试

RSpec.describe 'something else' do
  before { subject.stubs(foo: 42) }
  it { subject.expects(:foo).never; subject.foo }
end

通过。我做错了什么?

我被Rails rspec undefined method `receive_message' for #<RSpec::ExampleGroups::引导到目前无效的解决方案,而我正在使用

RSpec 3.7
  - rspec-core 3.7.1
  - rspec-expectations 3.7.0
  - rspec-mocks 3.7.0
  - rspec-support 3.7.1

更新1:我使用webmock代替rspec-mocks

更新2:我正在使用webmockmocha

更新3:感谢所有的解释,@ engineersmnky!不幸的是,对于我的特定用例,我仍然需要存根方法。为什么这个仍在传递?

require 'rspec'
require 'mocha'

RSpec.configure do |config|
  config.mock_with :mocha
end

RSpec.describe 'something' do
  # passes
  it 'can hide from foo' do 
    subject.stubs(:foo)
    expects(:foo).never
    subject.foo
  end
end

不同之处在于我试图表达我希望永远不会发送信号:foo

1 个答案:

答案 0 :(得分:4)

好的,这里有2个问题。首先,您正在尝试使用mocha作为模拟框架工作的rspec期望语法。这导致:

undefined method `receive' for #<RSpec::ExampleGroups::Something:0x0000000010391588>

错误,因为mocha不了解receivemocha的语法应为:

it { expects(:foo).never }  

你的下一个问题是前一块是短脚本foo所以它实际上永远不会到达接收器。因此,您的第二种情况通过,因为subject实际上从未收到foo,因为存根拦截了呼叫。

示例:

require 'rspec'
require 'mocha'

RSpec.configure do |config|
  config.mock_with :mocha
end

def stub_obj(obj,method_list)
  Class.new(SimpleDelegator) do 
      method_list.each do |k,v| 
          define_method(k) {v}
      end
  end.new(obj)
end

RSpec.describe 'something' do

  subject {mock('subject')}
  #passes 
  it { expects(:foo).never }
  # fails 
  it { subject.expects(:foo).never; subject.foo }
  # passes 
  it 'can hide from foo' do 
    subject.stubs(:foo)
    subject.expects(:foo).never
    subject.foo
  end

  context 'kind of like this' do
    # passes
    it 'hides with a stubbed method' do
      stubber = stub_obj(subject, foo: 'bar')
      subject.expects(:foo).never
      stubber.foo
    end
    # fails 
    it 'cannot hide from a non-stubbed method' do
      stubber = stub_obj(subject, foo: 'bar')
      subject.expects(:bar).never
      stubber.bar
    end
  end
end

如果您感兴趣,这是Object#stubs的实现,虽然它比我的示例(#stub_obj)通过Mocha::Mockery对象做的更多,但概念是相同的。