test practices example better best ruby tdd rspec2

ruby - practices - Rspec: espera frente a espera con bloque, ¿cuál es la diferencia?



rspec capybara best practices (2)

Como se ha mencionado:

expect(4).to eq(4)

Esto es específicamente probar el valor que ha enviado como parámetro al método. Cuando intentas probar errores planteados cuando haces lo mismo:

expect(raise "fail!").to raise_error

Su argumento se evalúa de inmediato y esa excepción se lanzará y su prueba explotará allí mismo.

Sin embargo, cuando usa un bloque (y esto es ruby ​​básico), el contenido del bloque no se ejecuta inmediatamente; su ejecución está determinada por el método que está llamando (en este caso, el método de expect controla cuándo ejecutar su bloque) :

expect{raise "fail!"}.to raise_error

Podemos ver un método de ejemplo que podría manejar este comportamiento:

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

Aquí puede ver que es el método de expect que está rescatando manualmente su error para que pueda probar si los errores se yield o no, etc. el yield es la forma en que un método ruby ​​de ejecutar cualquier bloque se le pasó al método.

Simplemente aprendiendo la sintaxis de rspec y noté que este código funciona:

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

Pero este código no lo hace:

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

Me da este error:

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)>''

Mi pregunta es:

  1. ¿Por qué pasó esto?
  2. ¿Cuál es la diferencia entre el ejemplo anterior y el anterior exactamente en ruby?

También estoy buscando reglas sobre cuándo usar una sobre la otra.

Un ejemplo más de los mismos resultados, pero inversos, donde funciona este código:

it "has a list of players" do expect(Team.new("Random").players).to be_kind_of Array end

Pero este código falla

it "has a list of players" do expect{ Team.new("Random").players }.to be_kind_of Array end

El error que recibo en este caso es:

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 clase que estoy probando se ve así:

class Team attr_reader :name, :players def initialize(name, players = []) raise Exception unless players.is_a? Array @name = name @players = players end end


En el primer caso, cuando pasa un bloque a expect , la ejecución del bloque no se produce hasta que llega el momento de evaluar el resultado, momento en el que el código RSpec puede detectar cualquier error que se genere y compararlo con la expectativa.

En el segundo caso, el error surge cuando se evalúa el argumento a expect , por lo expect código de expect no tiene oportunidad de involucrarse.

En cuanto a las reglas, pasa un bloque o un Proc si está tratando de probar el comportamiento (por ejemplo, aumentar errores, cambiar algún valor). De lo contrario, pasa un argumento "convencional", en cuyo caso el valor de ese argumento es lo que se prueba.