首页 文章

Rails - RSpec NoMethodError:未定义的方法

提问于
浏览
0

我正在尝试测试一个非常简单的方法,它接收2个数字并使用它们计算出一个百分比 . 但是,当我尝试运行测试时,它失败并出现以下错误:

NoMethodError: undefined method `pct' for Scorable:Module
./spec/models/concerns/scorable_spec.rb:328:in `block (2 levels) in 
<top (required)>'
./spec/rails_helper.rb:97:in `block (3 levels) in <top (required)>'
./spec/rails_helper.rb:96:in `block (2 levels) in <top (required)>'
-e:1:in `<main>'

这是我的模块的spec文件:

require 'rails_helper'
RSpec.describe Scorable, :type => :concern do

  it "pct should return 0 if den is 0 or nil" do
    expect(Scorable.pct(nil, 15)).to eq(0)
    expect(Scorable.pct(0, 15)).to eq(0)
  end

end

这是位于Scorable.rb中的pct方法:

def pct(num,den)
  return 0 if num == 0 or num.nil?
  return (100.0 * num / den).round
end

这是我的rspec_helper:

if ENV['ENABLE_COVERAGE']
   require 'simplecov'
   SimpleCov.start do
   add_filter "/spec/"
   add_filter "/config/"
   add_filter '/vendor/'

   add_group 'Controllers', 'app/controllers'
   add_group 'Models', 'app/models'
   add_group 'Helpers', 'app/helpers'
   add_group 'Mailers', 'app/mailers'
   add_group 'Views', 'app/views'
 end
end

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
  expectations.include_chain_clauses_in_custom_matcher_descriptions = 
  true
end
config.raise_errors_for_deprecations!

 config.mock_with :rspec do |mocks|
   mocks.verify_partial_doubles = true
 end
end

我对RSpec非常陌生,并且对这个问题感到困惑超过一天 . 它肯定指向一个现有的方法,因为当我在RubyMine中使用Go To Declaration时,它会打开方法声明 . 任何人都可以为我揭开这一点吗?我敢肯定我会忽略一些非常简单的事情 .

1 回答

  • 2

    要使用 Module.method 表示法调用模块方法,应在模块范围内声明 .

    module Scorable
      def self.pct(num,den)
        return 0 if num == 0 or num.nil?
        return (100.0 * num / den).round
      end
    end
    

    要么:

    module Scorable
      class << self
        def pct(num,den)
          return 0 if num == 0 or num.nil?
          return (100.0 * num / den).round
        end
      end
    end
    

    或者Module#module_function

    module Scorable
      module_function
      def pct(num,den)
        return 0 if num == 0 or num.nil?
        return (100.0 * num / den).round
      end
    end
    

    注意,后者在此模块中声明了模块方法和普通实例方法 .


    旁注:在方法的最后一行使用 return 被认为是代码气味,应该避免:

    module Scorable
      def self.pct(num,den)
        return 0 if num == 0 or num.nil?
        (100.0 * num / den).round
      end
    end
    

相关问题