由于使用ARGV而不是.gets,RSpec测试失败

时间:2019-04-30 13:25:16

标签: ruby rspec

我正在构建一个程序,该程序需要从用户那里获取一个数字,但是当运行这样的程序时,用户会将其作为参数在控制台中传递:“ ruby​​ name_of_program.rb --number 25”最初是.chomp(),但由于它没有收集参数25,所以我很快将其更改为ARGV。我所有的RSpec测试都失败了,并且收到以下消息:TypeError:无法将nil强制转换为Integer。我正试图找出原因。我的程序按预期工作。我如何才能使测试再次正常工作?

first_number = 2

given_number = ARGV.last
given_number = given_number.to_i

arr = []

def prime_numbers(first_number, given_number, arr)

  while(first_number <= given_number)
    prime_number = true
    x = 2

    while (x <= first_number / 2)
      if (first_number % x == 0)
        prime_number = false
        break
      end
      x += 1
    end

    if prime_number
      arr << first_number
    end

    first_number += 1
  end

  return arr

end

示例测试:

require 'prime_factors'

RSpec.describe 'prime_factors' do
  let(:array_one) { [2, 3, 5, 7] }
  let(:empty_array) { [] }
  let(:first_number) { 2 }

      context 'prime_numbers function' do

        it 'returns a list of prime numbers for a range 2 - 10 ' do
          given_number = 10
          expect(prime_numbers(first_number, given_number, empty_array)).to eq [2, 3, 5, 7]
        end


    end
    end

3 个答案:

答案 0 :(得分:2)

当您require执行此程序时(看起来似乎会做),它会计算ARGV.last并返回nil,因为ARGV(可能)是一个空数组。

我将prime_numbers的定义放到一个单独的文件中,并在您的rspec测试中要求该文件。

答案 1 :(得分:1)

先前的答案为您提供了正确的方法,但是,如果您想使用命令行参数来测试程序,则可以这样做。为简单起见,我删除了命令行参数的标记,仅传递了2个数字,但您可以根据需要进行修改:

#app.rb

first_number = ARGV.first.to_i
given_number = ARGV.last.to_i

arr = []

def prime_numbers(first_number, given_number, arr)

  while(first_number <= given_number)
    prime_number = true
    x = 2

    while (x <= first_number / 2)
      if (first_number % x == 0)
        prime_number = false
        break
      end
      x += 1
    end

    if prime_number
      arr << first_number
    end

    first_number += 1
  end

  return arr

end

print prime_numbers(first_number, given_number, arr)

您的规格文件

#spec/app_spec.rb

RSpec.describe 'prime_factors' do
  let(:exec) { File.expand_path('../app.rb', File.dirname(__FILE__)) }

  describe 'app' do
    it 'returns a list of prime numbers for a range 2 - 10 ' do
      given_number = 10
      res = `ruby #{exec} #{2} #{10}`
      expect(res).to eq '[2, 3, 5, 7]'
    end
  end
end

如果您想在命令行参数中传递标志,则可以使用以下内容解析数字:

args = ARGV.map(&:to_i).select{|arg| arg > 0}

first_number = args.first
given_number = args.last

答案 2 :(得分:0)

我已将prime_factors.rb拆分为3个单独的文件,并相应地在prime_factors_spec.rb中要求它们。非常感谢你们!