2016-12-30 5 views
1

J'écris une interface de ligne de commande à une gemme Ruby et j'ai cette méthode exit_error, qui agit comme un point d'erreur de sortie à toutes les validations effectuées pendant le traitement.Écriture d'un test Rspec pour une condition d'erreur terminée avec la sortie

def self.exit_error(code,possibilities=[]) 
    puts @errormsgs[code].colorize(:light_red) 
    if not possibilities.empty? then 
    puts "It should be:" 
    possibilities.each{ |p| puts " #{p}".colorize(:light_green) } 
    end 
    exit code 
end 

@errormsgs est une table de hachage dont les clés sont les codes d'erreur et dont les valeurs sont des messages d'erreur correspondants.

De cette façon, je peux donner aux utilisateurs des messages d'erreur personnalisés écriture de validation comme:

exit_error(101,@commands) if not valid_command? command 

où:

@errormsgs[101] => "Invalid command." 
@commands = [ :create, :remove, :list ] 

et l'utilisateur en tapant une commande erronée serait un message d'erreur comme:

Invalid command. 
It should be: 
    create 
    remove 
    list 

Dans le même temps, je peux avoir des scripts bash détectant exactement le code d'erreur qui a causé la condition de sortie, et c'est très important pour ma gemme.

Tout fonctionne bien avec cette méthode et cette stratégie dans son ensemble. Mais je dois avouer que j'ai écrit tout cela sans écrire d'abord des tests. Je sais, je sais ... Honte à moi! Maintenant que j'en ai terminé avec la gemme, je veux améliorer mon taux de couverture de code. Tout le reste a été fait par le livre, en écrivant les tests d'abord et en codant après les tests. Donc, ce serait bien d'avoir des tests pour ces conditions d'erreur aussi.

Il se trouve que je ne sais vraiment pas comment écrire des tests Rspec dans cette situation particulière, lorsque j'utilise exit pour interrompre le traitement. Aucune suggestion?

Mise à jour => Cette gemme fait partie d'un "environnement de programmation" rempli de scripts bash. Certains de ces scripts doivent connaître exactement la condition d'erreur qui a interrompu l'exécution d'une commande pour agir en conséquence.

+0

Qu'est-ce que vous voulez faire avec 'bash' exactement? – Inian

+0

@Inian cette gemme fait partie d'un "environnement de programmation" qui a beaucoup de scripts bash. Certains de ces scripts doivent connaître les codes d'erreur renvoyés par cette interface de ligne de commande Ruby, afin qu'ils puissent agir en conséquence. –

+0

Vous pouvez obtenir le code de retour de n'importe quelle commande en faisant '$?', Vous pouvez directement vérifier sa valeur pour la vérification de succès/échec. – Inian

Répondre

2

Par exemple:

class MyClass 
    def self.exit_error(code,possibilities=[]) 
    puts @errormsgs[code].colorize(:light_red) 
    if not possibilities.empty? then 
     puts "It should be:" 
     possibilities.each{ |p| puts " #{p}".colorize(:light_green) } 
    end 
    exit code 
    end 
end 

Vous pouvez écrire son rspec être quelque chose comme ceci:

describe 'exit_error' do 
    let(:errormsgs) { {101: "Invalid command."} } 
    let(:commands) { [ :create, :remove, :list ] } 
    context 'exit with success' 
    before(:each) do 
     MyClass.errormsgs = errormsgs # example/assuming that you can @errormsgs of the object/class 
     allow(MyClass).to receive(:exit).with(:some_code).and_return(true) 
    end 

    it 'should print commands of failures' 
     expect(MyClass).to receive(:puts).with(errormsgs[101]) 
     expect(MyClass).to receive(:puts).with("It should be:") 
     expect(MyClass).to receive(:puts).with(" create") 
     expect(MyClass).to receive(:puts).with(" remove") 
     expect(MyClass).to receive(:puts).with(" list") 
     MyClass.exit_error(101, commands) 
    end 
    end 

    context 'exit with failure' 
    before(:each) do 
     MyClass.errormsgs = {} # example/assuming that you can @errormsgs of the object/class 
     allow(MyClass).to receive(:exit).with(:some_code).and_return(false) 
    end 

    # follow the same approach as above for a failure 
    end 
end 

Bien sûr, cela est une prémisse pour vos spécifications et pourrait ne pas fonctionner que si vous copiez et collez le code. Vous devrez faire un peu de lecture et de refactoring afin d'obtenir des signaux verts de rspec.

+0

Merci! Oui, je sais que je vais devoir m'adapter, mais vous m'avez mis sur la bonne voie. Je n'avais aucune idée sur la façon de le démarrer. –