Rspec/mocks raises uninitialized constant BasicObject::RSpec

橙三吉。 提交于 2020-01-15 03:28:09

问题


I just installed rspec and rspec-mocks but I am not able to run the simplest setup

irb(main):001:0> require 'rspec'
=> true
irb(main):004:0> require 'rspec/mocks'
=> false
irb(main):006:0> RSpec::Mocks::setup(Object.new)
NameError: uninitialized constant BasicObject::RSpec
    from /usr/local/Cellar/ruby/1.9.1-p376/lib/ruby/gems/1.9.1/gems/rspec-mocks-2.13.0/lib/rspec/mocks.rb:60:in `block in add_extensions'
    from /usr/local/Cellar/ruby/1.9.1-p376/lib/ruby/gems/1.9.1/gems/rspec-mocks-2.13.0/lib/rspec/mocks.rb:60:in `class_eval'
    from /usr/local/Cellar/ruby/1.9.1-p376/lib/ruby/gems/1.9.1/gems/rspec-mocks-2.13.0/lib/rspec/mocks.rb:60:in `add_extensions'
    from /usr/local/Cellar/ruby/1.9.1-p376/lib/ruby/gems/1.9.1/gems/rspec-mocks-2.13.0/lib/rspec/mocks.rb:11:in `setup'
    from (irb):6
    from /usr/local/Cellar/ruby/1.9.1-p376/bin/irb:12:in `<main>'

I wonder what could be wrong, do I need to load some other gem?


回答1:


If you're stuck with Ruby 1.9.1, I think I've got a solution for you but a warning -- this is a bit of hack!

If you look at your error message, it says the failure is on line 60 of /lib/rspec/mocks.rb. So lets take a look at: https://github.com/rspec/rspec-mocks/blob/v2.13.0/lib/rspec/mocks.rb

def add_extensions
  method_host.class_eval { include RSpec::Mocks::Methods } # (line 60)
  Class.class_eval  { include RSpec::Mocks::AnyInstance }
  $_rspec_mocks_extensions_added = true
end

Notice that this private method's first line (line 60) is calling 'method_host'. So lets take a look down a few lines at the private method 'method_host':

def method_host
  # On 1.8.7, Object.ancestors.last == Kernel but
  # things blow up if we include `RSpec::Mocks::Methods`
  # into Kernel...not sure why.
  return Object unless defined?(::BasicObject)

  # MacRuby has BasicObject but it's not the root class.
  return Object unless Object.ancestors.last == ::BasicObject

  ::BasicObject
end

You can see that there are a couple conditions where it sometimes returns 'Object' and otherwise returns 'BasicObject'. So, it made me wonder if we couldn't add our own condition.

return Object unless defined?(::BasicObject::RSpec)

We can test this by creating a file, lets call it mocks_hack.rb where we'll redefine 'method_host' to include our condition.

module RSpec
  module Mocks
    class << self

    private

      def method_host
        # On 1.8.7, Object.ancestors.last == Kernel but
        # things blow up if we include `RSpec::Mocks::Methods`
        # into Kernel...not sure why.
        return Object unless defined?(::BasicObject)

        # MacRuby has BasicObject but it's not the root class.
        return Object unless Object.ancestors.last == ::BasicObject

        # Jon's hack for Anurag Uniyal
        return Object unless defined?(::BasicObject::RSpec)

        ::BasicObject
      end
    end
  end
end

From the current directory of mocks_hack.rb, launching irb and the following code should 'work'.

require 'rspec'
require './mocks_hack'
RSpec::Mocks::setup(Object.new)

Now, this comes with a disclaimer -- it's a hack and I don't fully understand what the implications of making this change might be. Hopefully it helps and is a viable workaround.




回答2:


Jonathan is on the right track, but the root of the problem is an incompatibility with 1.8.7, since ::BasicObject still exists in Ruby 1.9.

A proper solution to what is the author is patching is more appropriately specified by limiting the patch to Ruby 1.8:

def method_host
  # On 1.8.7, Object.ancestors.last == Kernel but
  # things blow up if we include `RSpec::Mocks::Methods`
  # into Kernel...not sure why.
  return Object unless defined?(::BasicObject) && RUBY_VERSION =~ /^1\.8\.\d+/

  # MacRuby has BasicObject but it's not the root class.
  return Object unless Object.ancestors.last == ::BasicObject

  ::BasicObject
end


来源:https://stackoverflow.com/questions/15282389/rspec-mocks-raises-uninitialized-constant-basicobjectrspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!