我刚刚安装了rspec和rspec-mocks,但我无法运行最简单的设置
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>'
我想知道可能出现什么问题,我是否需要加载其他宝石?
答案 0 :(得分:2)
Jonathan走在正确的轨道上,但问题的根源是与1.8.7的不兼容,因为:: BasicObject仍然存在于Ruby 1.9中。
通过将 patch 限制为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
答案 1 :(得分:0)
如果你坚持使用Ruby 1.9.1,我想我已经为你找到了一个解决方案,但是一个警告 - 这是一个黑客攻击!
如果查看错误消息,则表示失败位于/lib/rspec/mocks.rb的第60行。我们来看看: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
请注意,此私有方法的第一行(第60行)正在调用'method_host'。因此,让我们看看私有方法'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
你可以看到有几个条件,它有时返回'Object',否则返回'BasicObject'。所以,它让我想知道我们是否无法添加自己的条件。
return Object unless defined?(::BasicObject::RSpec)
我们可以通过创建一个文件来测试它,让我们称之为mocks_hack.rb,我们将重新定义'method_host'以包含我们的条件。
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
从mocks_hack.rb的当前目录中,启动irb和以下代码应该“正常”。
require 'rspec'
require './mocks_hack'
RSpec::Mocks::setup(Object.new)
现在,这带有免责声明 - 这是一个黑客攻击,我不完全明白做出这种改变可能带来的影响。希望它有所帮助并且是一种可行的解决方法。