【问题标题】:unit testing a ruby command line application's code - how to simulate/pass ARGV's单元测试 ruby​​ 命令行应用程序的代码 - 如何模拟/通过 ARGV
【发布时间】:2011-12-24 00:06:12
【问题描述】:

我有一个命令行应用程序,它使用 thor 来处理选项的解析。我想使用 test-unit 和/或 minitest 针对代码对命令行功能进行单元测试。

我似乎不知道如何确保 ARGV 数组(通常会保存命令行中的选项)保存我的测试选项,以便可以针对代码进行测试。

具体应用代码:

# 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

可执行文件

# bin/myapp

测试文件

# 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

我已经能够在测试类中将一个数组传递给 ARGV,但是一旦我调用 Myapp/Commands/Build,ARGV 似乎是空的。我需要确保 ARGV 数组包含“build”和“html”,以使 Build 命令正常工作并通过。

【问题讨论】:

    标签: ruby testing command-line gem thor


    【解决方案1】:

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

    ARGV.replace your_argv
    

    发现于http://apidock.com/ruby/Test/Unit/setup_argv/class

    【讨论】:

      【解决方案2】:

      更好的模式是抽象出ARGV 的直接使用来进行测试。鉴于您当前的设计,您可以创建一个名为 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 提供支持的可执行文件中使用它们(而不是将所有代码都放在可执行文件中),可能会为您提供更好的服务。

      【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-27
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多