【问题标题】:Using default options when testin thor tasks测试任务时使用默认选项
【发布时间】:2012-11-23 20:11:39
【问题描述】:

我想用 rspec 测试 thor 任务,但是从 rspec 调用它们时我有两个要求:

  1. 我想要 Thor 类实例可用
  2. 我想使用默认选项调用任务(因为它将从命令行调用)

我无法同时实现这两个,请考虑以下代码:

require 'thor'
require 'thor/runner'
class App < Thor
  method_option :foo , :default => "foovalue"
  desc "xlist", "list"
  def xlist(search="")
    p options
  end
end

app = App.new

app.xlist
app.invoke(:xlist)

App.start ARGV

输出是:

> ruby contrib/thor_test.rb xlist
{}
{}
{"foo"=>"foovalue"}

在前两个示例中,我可以通过实例调用任务,但默认选项不会传递给方法(这使得规范不切实际)

在第三个示例中,我获得了默认选项,但我无法对类实例设置期望值,也无法存根任何难以测试的方法。这是因为类实例是动态创建的。

【问题讨论】:

    标签: thor


    【解决方案1】:

    如果您问如何测试 thor cli 实用程序,我会按照 this SO answer 中的建议通读 thor 规范。示例here 特别有用,可以直接使用。

    规格:

    require 'my_thor'
    
    describe MyThor do
      it "should work" do
        args = ["command", "--force"]
        options = MyThor.start(args)
        expect(options).to eq({ "force" => true })
      end
    end
    

    代码:

    class MyThor < Thor
      desc "command", "do something"   
      method_option :force, :type => :boolean, :aliases => '-f'
      def command
        return options
      end
    end
    

    【讨论】:

    • 这里没有说明如何测试 default 选项,因为你明确地传入了 '--force'
    【解决方案2】:

    我能够通过以下方式提取 Thor 命令的默认选项:

    1. 获取 Thor 对该命令的选项列表的内部表示
    2. 从该命令列表构建一个Thor::Options 对象
    3. 使用 Thor::Options 对象解析一个空的选项数组,该数组仅返回默认值的哈希值。

    代码在下面的get_default_options_for_command。老实说,我希望有更好的方法来做到这一点,但我找不到。

    获得 Thor 对象后,您可以替换其选项以包含这些默认值以及您想要添加的任何其他选项,然后使用 #xlist 运行它。

    我用你上面的例子写了这一切:

    require 'thor'
    
    def get_default_options_for_command(klass,command_name)
      option_precursors = klass.all_commands[command_name].options
      parser = Thor::Options.new(option_precursors)
      parser.parse([])
    end
    
    class App < Thor
    
      desc "xlist", "list"
      method_option :foo , :default => "foovalue"
      method_option :bar
      def xlist(search="")
        puts "search: #{search}"
        puts "options: #{options}"
      end
    end
    
    app = App.new
    xlist_default_opts = get_default_options_for_command(App,'xlist')
    new_opts = { :bar => 3 }
    
    app.options = xlist_default_opts.merge(new_opts)
    app.xlist('search-term')
    

    输出是:

    $ ./test.rb
    search: search-term
    options: {"foo"=>"foovalue", "bar"=>3}
    

    【讨论】:

      猜你喜欢
      • 2017-11-26
      • 1970-01-01
      • 2018-02-08
      • 2015-09-09
      • 1970-01-01
      • 2016-01-09
      • 2020-02-08
      • 1970-01-01
      • 2017-03-23
      相关资源
      最近更新 更多