5

所以,我的 ruby​​ 代码中有一个模块,看起来像这样:

module MathStuff
  class Integer
    def least_factor
      # implementation code
    end
  end
end

我有一些 RSpec 测试,我想在其中测试我的Integer#least_factor方法是否按预期工作。为了简单起见,我们会说测试在同一个文件中。测试看起来像这样:

describe MathStuff do
  describe '#least_factor' do
    it 'returns the least prime factor' do
      expect(50.least_factor).to eq 2
    end
  end
end

不幸的是,当我运行测试时,我收到如下错误:

NoMethodError:
    undefined method `least_factor' for 50:Fixnum

如果您知道如何将MathStuff::Integer课程包括在内进行测试,请告诉我。

注意:为了澄清起见,我实际上是在尝试在这里打开 Ruby Integer 类并向其添加方法。

4

3 回答 3

3

您的代码应如下所示:

describe MathStuff::Integer do
  describe '#least_factor' do
    it 'returns the least prime factor' do
      expect(MathStuff::Integer.new.least_factor).to eq 2
    end
  end
end

但是您正在调用50.least_factor,并且 50 是一个Fixnum对象,而不是您的对象,MathStuff::Integer并且它没有定义该方法。

于 2013-10-06T04:22:43.587 回答
3

在 Ruby 2.1中添加改进(以及 2.0 中的实验性支持)之前,您不能将这样的猴子补丁的范围限制为特定的上下文(即模块)。

但是您的示例不起作用的原因是在 Mathstuff 模块下定义一个 Integer 类会创建一个与 Integer 核心类无关的新类。覆盖核心类的唯一方法是在顶层(而不是模块内)打开该类。

我通常将核心扩展放在 lib/core_ext 子目录中,以它们正在修补的类命名,在您的情况下为 lib/core_ext/integer.rb。

于 2013-10-06T05:18:09.637 回答
0

简单但不推荐的方式:

require "rspec"

class Integer
  def plus_one
    self + 1
  end
end

describe 'MathStuff' do
  describe '#plus_one' do
    it 'should be' do
      expect(50.plus_one).to eq 51
    end
  end
end

$ rspec test.rb
.

Finished in 0.01562 seconds
1 example, 0 failures
于 2013-10-06T04:55:57.980 回答