Unit testing ruby ​​command-line application code - how to simulate / transmit ARGV

I have a command line application that uses thor to handle parameter parsing. I want unit test to use command line functionality for code with a test block and / or mini test.

I cannot figure out how to make sure that the ARGV array (which usually holds command line parameters) contains my test parameters so that they can be tested against the code.

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 

Executable file

 # bin/myapp 

Test file

 # tests/test_build_html.rb require 'test/unit' require 'myapp/commands/build' class TestBuildHtml < Test::Unit::TestCase include Myapp::Commands # HERE 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 managed to pass the array to ARGV in the test class, but as soon as I call Myapp / Commands / Build, ARGV turns out to be empty. I need to make sure that the ARGV array contains "build" and "html" for the Build command to work, and this needs to be passed.

+7
source share
4 answers

The easiest way to install ARGV and avoid the warning:

 ARGV.replace your_argv 

Found at http://apidock.com/ruby/Test/Unit/setup_argv/class

+4
source

A better option would be to abstract away the direct use of ARGV for testing. Given your current design, you can make a module called something like CommandLineArguments and grant access this way:

 module CommandLineArguments def argv; ARGV; end end 

In your main code:

 class Build < Thor::Group include CommandLineArguments include Thor::Actions args = argv build = args.shift 

Finally, in your test, you can change the module or test class:

 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 

If this seems rather complicated, it is. You might be better off serving to extracting most of your code into the actual classes, and then use them in the Toror executable (instead of having all this code in the executable).

+2
source

Have you tried ARGV = ['build', 'html']?

You may receive a warning, but it should give you the desired affect.

According to this , you don’t even need to use ARGV at all.

0
source

ARGV.concat %w{build html} , for example ?!

0
source

All Articles