1

我想用 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"}

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

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

4

2 回答 2

3

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

规格:

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
于 2013-03-23T00:34:20.310 回答
1

我能够通过以下方式提取 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}
于 2015-03-11T17:42:30.630 回答