2011-12-24 3 views
7

Ho un'applicazione di riga di comando che utilizza thor per gestire l'analisi delle opzioni. Voglio testare la funzionalità della riga di comando contro il codice con test-unit e/o minitest.unità di test di un codice dell'applicazione di riga di comando ruby ​​- come simulare/passare ARGV's

Non riesco a capire come assicurarsi che l'array ARGV (che normalmente terrebbe le opzioni dalla riga di comando) mantiene le mie opzioni di test in modo che possano essere testate contro il codice.

Il codice specifica applicazione:

# 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 

L'eseguibile

# bin/myapp 

Il file di prova

# 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 

sono stato in grado di passare un array in ARGV nella classe di test, ma una volta che chiamo Myapp/Commands/Build the ARGV sembra essere vuoto. Devo assicurarmi che l'array ARGV tenga "build" e "html" affinché il comando Build funzioni e questo passi.

risposta

0

Hai provato ARGV = ['build', 'html']?

È possibile che venga visualizzato un messaggio di avvertenza, ma che dovrebbe fornire l'effetto desiderato.

Secondo lo standard this non è nemmeno necessario utilizzare l'ARGV.

2

Un modello migliore sarebbe quello di astrarre l'utilizzo diretto di ARGV per il test. Dato il design corrente, si potrebbe fare un modulo chiamato qualcosa come CommandLineArguments e fornire accesso in questo modo:

module CommandLineArguments 
    def argv; ARGV; end 
end 

Nel codice principale:

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

    args = argv 
    build = args.shift 

Infine, nel test, è possibile modificare il modulo o la tua classe di test:

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 

Se questo sembra piuttosto complesso, lo è. Potrebbe essere meglio servire estraendo la maggior parte del codice in classi reali e quindi utilizzarle nel tuo eseguibile potenziato da Thor (piuttosto che avere tutto quel codice nell'eseguibile).

+0

Grazie, Dave! Esattamente quello che stavo cercando. Nel frattempo ho finito per leggere il tuo libro [Building Awesome Command-Line Applications in Ruby] (http://pragprog.com/book/dccar/build-awesome-command-line-applications-in-ruby). ;-) Ho implementato Aruba con cetriolo per ottenere almeno il test di accettazione in corso. –

0

ARGV.concat %w{build html}, per esempio ?!