6

I have a command-line application which uses thor to handle the parsing of options. I want to unit test the command-line functionality against the code with test-unit and/or minitest.

I can't seem to figure out how to make sure the ARGV array (which normally would hold the options from the command line) holds my test options so they can be tested against the code.

The specific application code:

# myapp/commands/build.rb
require 'thor'

module Myapp
  module Commands

    # Define build commands for MyApp command line
    class Build < Thor::Group
      include Thor::Actions

      build = ARGV.shift
      build = aliases[build] || build

      # Define arguments and options
      argument :type
      class_option :test_framework, :default => :test_unit

      # Define source root of application
      def self.source_root
        File.dirname(__FILE__)
      end

      case build

      # 'build html' generates a html
      when 'html'

        # The resulting html
        puts "<p>HTML</p>"
      end
    end
  end
end

The executable

# bin/myapp

The Test File

# tests/test_build_html.rb

require 'test/unit'
require 'myapp/commands/build'


class TestBuildHtml < Test::Unit::TestCase
  include Myapp::Commands

  # HERE'S WHAT I'D LIKE TO DO
  def test_html_is_built

    # THIS SHOULD SIMULATE 'myapp build html' FROM THE COMMAND-LINE
    result = MyApp::Commands::Build.run(ARGV << 'html')
    assert_equal result, "<p>HTML</p>"
  end

end

I have been able to pass an array into ARGV in the test class, but once I call Myapp/Commands/Build the ARGV appears to be empty. I need to make sure the ARGV array is holding 'build' and 'html' in order for the Build command to work and this to pass.

4

4 回答 4

5

设置 ARGV 并避免警告的最简单方法是:

ARGV.replace your_argv

http://apidock.com/ruby/Test/Unit/setup_argv/class中找到

于 2013-12-14T10:09:42.033 回答
2

更好的模式是抽象出ARGVfor testing 的直接用法。鉴于您当前的设计,您可以制作一个名为类似的模块CommandLineArguments并以这种方式提供访问权限:

module CommandLineArguments
  def argv; ARGV; end
end

在您的主要代码中:

class Build < Thor::Group
  include CommandLineArguments
  include Thor::Actions

  args = argv
  build = args.shift

最后,在您的测试中,您可以修改模块或您的测试类:

def setup
  @myargs = nil
end

class MyApp::Commands::Build
  def argv; @myargs || ARGV; end
end

def test_html_is_built
  @myargs = %w(html)
  result = MyApp::Commands::Build.run
end

如果这看起来相当复杂,那就是。将大部分代码提取到实际类中,然后在由 Thor 驱动的可执行文件中使用它们(而不是将所有代码都放在可执行文件中),可能会更好地为您服务。

于 2011-12-31T18:39:32.540 回答
1

ARGV.concat %w{build html}, 例如?!

于 2015-05-18T17:51:17.063 回答
0

你试过 ARGV = ['build', 'html'] 吗?

您可能会收到警告,但它应该会给您想要的效果。

据此,您甚至根本不需要使用 ARGV。

于 2011-12-24T20:04:01.100 回答