在testin thor任务中使用默认选项

时间:2012-11-23 20:11:39

标签: thor

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

  1. 我想提供Thor Class实例
  2. 我想用默认选项调用任务(因为它将从命令行调用)
  3. 我无法同时实现这两个目标,请考虑以下代码:

    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"}
    

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

    在第三个例子中,我得到了默认选项,但我无法设置类实例的期望,也不能存储任何难以测试的方法。这种情况正在发生,因为类实例是即时创建的。

2 个答案:

答案 0 :(得分:3)

如果你问如何测试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

答案 1 :(得分:0)

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

  1. 获取Thor对该命令的选项列表的内部表示
  2. 从该命令列表构建Thor::Options对象
  3. 使用该Thor::Options对象来解析一个空的数组选项,这些选项只返回默认值的哈希值。
  4. 代码位于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}