Testing a Class inside of a Module with RSpec

Deadly 提交于 2020-01-02 04:34:32

问题


So, I have a module in my ruby code which looks something like this:

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

and I have some RSpec tests in which I would like to test that my Integer#least_factor method works as expected. we'll say that the tests are in the same file for simplicity. The tests look something like this:

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

Unfortunately, when I run the tests, I get an error like this:

NoMethodError:
    undefined method `least_factor' for 50:Fixnum

Please let me know if you know how to include the MathStuff::Integer class for testing.

Note: just for clarification, I am actually trying to open up the Ruby Integer class here and add methods to it.


回答1:


Your code should look like:

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

But you're calling 50.least_factor and 50 is a Fixnum object, not your MathStuff::Integer and it doesn't have that method defined.




回答2:


Before the addition of refinements in Ruby 2.1 (and experimental support in 2.0), you couldn't limit the scope of a monkeypatch like this to a particular context (i.e. a module).

But the reason your example doesn't work is that defining an Integer class under the Mathstuff module creates a new class which has nothing to do with the Integer core class. The only way to override the core class is to open the class at the top level (not within a module).

I usually put core extensions in a lib/core_ext subdirectory, named after the class they are patching, in your case lib/core_ext/integer.rb.




回答3:


Simple but not recomended way:

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


来源:https://stackoverflow.com/questions/19205352/testing-a-class-inside-of-a-module-with-rspec

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