Je viens d'apprendre la syntaxe rspec et j'ai remarqué que ce code fonctionne:
context "given a bad list of players" do
let(:bad_players) { {} }
it "fails to create given a bad player list" do
expect{ Team.new("Random", bad_players) }.to raise_error
end
end
Mais ce code ne:
context "given a bad list of players" do
let(:bad_players) { {} }
it "fails to create given a bad player list" do
expect( Team.new("Random", bad_players) ).to raise_error
end
end
Cela me donne cette erreur:
Team given a bad list of players fails to create given a bad player list
Failure/Error: expect( Team.new("Random", bad_players) ).to raise_error
Exception:
Exception
# ./lib/team.rb:6:in `initialize'
# ./spec/team_spec.rb:23:in `new'
# ./spec/team_spec.rb:23:in `block (3 levels) in <top (required)>'
Ma question est:
Je cherche aussi règles sur quand utiliser l'un sur l'autre
Un autre exemple des mêmes résultats mais inversés, où ce code fonctionne:
it "has a list of players" do
expect(Team.new("Random").players).to be_kind_of Array
end
Mais ce code échoue
it "has a list of players" do
expect{ Team.new("Random").players }.to be_kind_of Array
end
L'erreur que j'obtiens dans ce cas est:
Failure/Error: expect{ Team.new("Random").players }.to be_kind_of Array
expected #<Proc:0x007fbbbab29580@/Users/amiterandole/Documents/current/Ruby_sandbox/tdd-Ruby/spec/team_spec.rb:9> to be a kind of Array
# ./spec/team_spec.rb:9:in `block (2 levels) in <top (required)>'
La classe que je teste ressemble à ceci:
class Team
attr_reader :name, :players
def initialize(name, players = [])
raise Exception unless players.is_a? Array
@name = name
@players = players
end
end
Comme cela a été mentionné:
expect(4).to eq(4)
Cela teste spécifiquement la valeur que vous avez envoyée en tant que paramètre à la méthode. Lorsque vous essayez de tester les erreurs déclenchées lorsque vous faites la même chose:
expect(raise "fail!").to raise_error
Votre argument est évalué immédiatement et cette exception sera levée et votre test explosera juste là.
Cependant, lorsque vous utilisez un bloc (et c'est Ruby de base), le contenu du bloc n'est pas exécuté immédiatement - son exécution est déterminée par la méthode que vous appelez (dans ce cas, la méthode expect
gère quand pour exécuter votre bloc):
expect{raise "fail!"}.to raise_error
Nous pouvons regarder un exemple de méthode qui pourrait gérer ce comportement:
def expect(val=nil)
if block_given?
begin
yield
rescue
puts "Your block raised an error!"
end
else
puts "The value under test is #{val}"
end
end
Vous pouvez voir ici que c'est la méthode expect
qui sauve manuellement votre erreur afin qu'elle puisse tester si des erreurs sont déclenchées, etc. yield
est le moyen d'une méthode Ruby l'exécution du bloc transmis à la méthode.
Dans le premier cas, lorsque vous passez un bloc à expect
, l'exécution du bloc ne se produit pas avant qu'il ne soit temps d'évaluer le résultat, auquel cas le code RSpec peut détecter toute erreur déclenchée et vérifier contre toute attente.
Dans le second cas, l'erreur est générée lorsque l'argument de expect
est évalué, de sorte que le code expect
n'a aucune chance de s'impliquer.
En ce qui concerne les règles, vous passez un bloc ou un Proc
si vous essayez de tester comportement (par exemple, augmenter les erreurs, changer une valeur). Sinon, vous passez un argument "conventionnel", auquel cas la valeur de cet argument est ce qui est testé.