我想用rspec测试thor任务,但是从rspec调用它时我有两个要求:
我无法同时实现这两个目标,请考虑以下代码:
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"}
在前两个示例中,我可以通过实例调用任务,但默认选项不会传递给方法(这使得规范不切实际)
在第三个例子中,我得到了默认选项,但我无法设置类实例的期望,也不能存储任何难以测试的方法。这种情况正在发生,因为类实例是即时创建的。
答案 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命令提取默认选项:
Thor::Options
对象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}