Comment utiliser should_raise de RSpec avec tout type d'exception?

211

Je voudrais faire quelque chose comme ça:

some_method.should_raise <any kind of exception, I don't care>

Comment dois-je procéder?

some_method.should_raise exception

... ne fonctionne pas.

marcgg
la source

Réponses:

380
expect { some_method }.to raise_error

Syntaxe RSpec 1:

lambda { some_method }.should raise_error

Consultez la documentation (pour la syntaxe RSpec 1) et la documentation RSpec 2 pour plus d'informations.

Avdi
la source
5
ahh .. je viens de remarquer les accolades!
Louis Sayers
88

RSpec 2

expect { some_method }.to raise_error
expect { some_method }.to raise_error(SomeError)
expect { some_method }.to raise_error("oops")
expect { some_method }.to raise_error(/oops/)
expect { some_method }.to raise_error(SomeError, "oops")
expect { some_method }.to raise_error(SomeError, /oops/)
expect { some_method }.to raise_error(...){|e| expect(e.data).to eq "oops" }

# Rspec also offers to_not:
expect { some_method }.to_not raise_error
...

Remarque: raise_erroret raise_exceptionsont interchangeables.

RSpec 1

lambda { some_method }.should raise_error
lambda { some_method }.should raise_error(SomeError)
lambda { some_method }.should raise_error(SomeError, "oops")
lambda { some_method }.should raise_error(SomeError, /oops/)
lambda { some_method }.should raise_error(...){|e| e.data.should == "oops" }

# Rspec also offers should_not:
lambda { some_method }.should_not raise_error
...

Remarque: raise_errorest un alias pour raise_exception.

Documentation: https://www.relishapp.com/rspec

RSpec 2:

RSpec 1:

joelparkerhenderson
la source
C'était une excellente réponse.
Ziggy
raise_error (/ oops /) est un excellent moyen de vérifier la sous-chaîne dans le message d'exception
Serge Seletskyy
1
Merci d'avoir souligné que raise_error et raise_exception sont interchangeables (y)
Yo Ludke
85

Au lieu de lambda, utilisez s'attendre à:

   expect { some_method }.to raise_error

Cela s'applique aux versions plus récentes de rspec, c'est-à-dire rspec 2.0 et plus.

Voir le doco pour plus.

rat
la source
Je ne l'utiliserais pas pour Rspec 1 mais pour Rspec 2 cela fonctionne comme il se doit.
ericraio
6
En fait, selon le lien de documentation ci-dessus, cela devrait être prévu {some_method} .to raise_error
Guilherme Garnier
Ni votre commentaire ni la page vers laquelle vous créez un lien n'explique pourquoi expectest meilleur ou pire que lambda.
Kragen Javier Sitaker
1
attendre pour rspec 2.0 et supérieur. Cela rend sans objet l'argument sur lequel est le meilleur, car la syntaxe lambda ne fonctionne plus
Rob
Cela ne fonctionne pas pour moi à capybara:expect { visit welcome_path }.to raise_error
nnyby
65

La syntaxe a changé récemment et c'est maintenant:

expect { ... }.to raise_error(ErrorClass)
ayckoster
la source
4

À partir de la version 3.3, rspec-expectionsgem émet un avertissement pour une erreur raise_error vide sans paramètre

expect { raise StandardError }.to raise_error # results in warning
expect { raise StandardError }.to raise_error(StandardError) # fine

Cela vous donne une indication que votre code peut échouer avec une erreur différente de celle du test destiné à vérifier.

AVERTISSEMENT: L'utilisation de la correspondance raise_errorsans fournir une erreur ou un message spécifique risque de faux positifs, car raise_errorcorrespondra lorsque Ruby déclenche un NoMethodError, NameErrorou ArgumentError, permettant potentiellement à l'attente de passer sans même exécuter la méthode que vous avez l'intention d'appeler. Envisagez plutôt de fournir une classe ou un message d'erreur spécifique. Ce message peut être supressed par le réglage: RSpec::Expectations.configuration.warn_about_potential_false_positives = false.

Bruno E.
la source