首页 > 解决方案 > 使用 rspec 测试 ARGV 选项。如何期望一个方法从另一个模块调用一个方法

问题描述

我正在用 Ruby 构建一个 CLI,我正在使用 ARGV 在命令行中传递选项和参数。我有一个在执行 CLI 时触发的调用方法。调用方法如下:

module Eltiempo
  class CLI
    def call
      help_menu if ARGV.count.zero?
      case ARGV[0]
      when '-today'
        raise NoCityError if ARGV[1].nil?

        Eltiempo.today(ARGV[1])
      when '-av_min'
        raise NoCityError if ARGV[1].nil?

        Eltiempo.av_min(ARGV[1])
      when '-av_max'
        raise NoCityError if ARGV[1].nil?

        Eltiempo.av_max(ARGV[1])
      when '-h'
        help_menu
      end
    end

在使用 rspec 对第一个案例选项(-today)进行测试时,我编写了以下代码:

RSpec.describe Eltiempo do
  describe '#call' do
    context 'given -today' do
      let(:ARGV) { ['-today', 'Barcelona'] }
      it 'calls function to return today\'s weather' do
        expect(Eltiempo::CLI.new.call).to receive(Eltiempo.today).with(ARGV[1])
      end
    end
  end
end

但是,在运行 rspec 时,它没有通过测试,它说:

Failure/Error:
       def self.today(city_name)
         max = max_today(city_name)
         min = min_today(city_name)
         puts "Weather today in #{city_name.capitalize}:
           - Maximum: #{max}°C
           - Minimum: #{min}°C"
       end
     
     ArgumentError:
       wrong number of arguments (given 0, expected 1)

它试图self.today(city_name)在ELTIEMPO模块中调用该方法,并在没有City_name参数的情况下运行,但是,我不希望它运行该方法,我只想检查该选项和参数-today Barcelona运行时,它会调用Eltiempo.today(ARGV[1])

为什么它在运行self.today(city_name)

标签: rubyrspec

解决方案


方法调用来自屋内!

expect(Eltiempo::CLI.new.call).to receive(Eltiempo.today).with(ARGV[1])
                                          ^^^^^^^^^^^^^^

这就是它的样子,一个Eltiempo.today没有参数的调用。

设置期望表示您期望特定对象接收特定方法。在这种情况下,这个对象是类Eltiempo。该方法通过名称作为符号传递。today在设置了将被调用的期望之后Eltiempo,您运行期望调用的代码Eltiempo.today

expect(Eltiempo).to receive(:today).with(ARGV[1])
Eltiempo::CLI.new.call

RSpec 已将todayon方法替换为Eltiempo记录它是否被调用并且不返回任何内容的方法。


推荐阅读