2011-11-04 13 views
15

Escribí un método de clase simple Buy.get_days(string), y estoy tratando de probarlo con diferentes entradas de cadena de texto. Sin embargo, creo que es muy detallado.Cómo probar métodos de clase en RSPEC

  • ¿Hay alguna forma más concisa de probar lo siguiente?
  • ¿Existe un equivalente de subject para métodos que acabo puedo seguir pasando parámetros diferentes y comprobar los resultados?
  • ¿Hay alguna manera de evitar la descripción innecesaria en cada it?

gracias

describe Buy do 
    describe '.get_days' do 
    it 'should get days' do 
     Buy.get_days('Includes a 1-weeknight stay for up to 4 people') 
     .should == 1 
     end 
    it 'should get days' do 
     Buy.get_days('Includes a 1-night stay in a King Studio Room with stone fireplace') 
     .should == 1 
    end 
    it 'should get days' do 
     Buy.get_days('Includes 4 nights/5 days at the Finisterra Hotel for up to two adults and two children (staying in the same room)') 
     .should == 4 
    end 
    end 
end 
+4

¿Cómo es la descripción 'it' innecesaria? El hecho de que hayas escrito el mismo texto para las especificaciones que prueban cosas diferentes no significa que la descripción no debería estar allí, ¿quizás reescribirlas para que sean útiles? –

+0

la combinación de entrada/salida es lo suficientemente descriptiva (al menos para mí). – lulalala

+0

¿Puedes dar un ejemplo de una nueva redacción para que sea más útil, @DaveNewton? – ahnbizcad

Respuesta

3

This es una forma interesante aunque quizás más obtusa de utilizar el bloque 'asunto' con los métodos de Clase.

Editar: El roto link según lo informado por el archivo Wayback, que supongo que es susceptible al mismo problema.

+1

[enlace roto] (http://posterous.timocracy.com/a-pattern-for-testing-class-methods-in-ruby-w) dice "Posterous Spaces ya no está disponible" –

+0

@JaredBeck editado. Resumiré la respuesta esta noche. – TCopple

+0

El contenido también está disponible como una esencia: https://gist.github.com/timocratic/816049 – aingram

11

no hay una subject equivalente para llamar a un método, por lo que usar it es el camino a seguir aquí. El problema que veo con su código tal como se presenta es que en realidad no explica qué está buscando. Me gustaría escribir algo más parecido a:

describe Buy do 
    describe '.get_days' do 
    it 'should detect hyphenated weeknights' do 
     Buy.get_days('Includes a 1-weeknight stay for up to 4 people').should == 1 
    end 
    it 'should detect hyphenated nights' do 
     Buy.get_days('Includes a 1-night stay in a King Studio Room with stone fireplace').should == 1 
    end 
    it 'should detect first number' do 
     Buy.get_days('Includes 4 nights/5 days at the Finisterra Hotel for up to two adults and two children (staying in the same room)').should == 4 
    end 
    end 
end 

estoy haciendo suposiciones acerca de lo que está buscando aquí, pero espero que la idea es clara. Esto también conducirá a una salida de error mucho más útil cuando falla una prueba. ¡Espero que esto ayude!

+0

Supongo que la respuesta al final es: no hay una manera más concisa de escribirlo. – lulalala

+0

Sí, miedo así. :) –

+0

@lulalala No * quiere * que sea conciso, quiere que sea preciso y descriptivo en el contexto de las especificaciones. –

0

Una alternativa al uso subject/it es utilizar before/specify:

describe '#destroy' do 
    context 'with children' do 
    before { @parent = FactoryGirl.create(:parent, children: FactoryGirl.create_list(:child, 2) } 
    specify { @parent.destroy.should be_false } 
    end 
end 

Esto producirá una descripción razonable en formato -fd salida de RSpec:

#destroy 
    with children 
    should be false 
5

Esto podría ser una cuestión de edad pero siempre puede usar subject.class para ir a:

describe Buy do 
    describe '.get_days' do 
    it { expect(subject.class.get_days('Includes a 1-weeknight stay for up to 4 people')).to eq 1 } 
    end 
end 
+0

Buena captura ! Facepalm. Debería haber sabido esto. ¡Esta es la respuesta correcta! – ahnbizcad

+1

'subject.class'? ¿No sería más claro usar 'Comprar'? –

+0

@ahnbizcad No realmente, porque esto muestra solo una prueba. Piense en la salida de la especificación y en lo que se supone que se muestra. Agregar las otras pruebas sin pruebas descriptivas genera resultados de especificaciones esencialmente inútiles porque no se sabe (a) qué está probando la especificación, y (b) qué diferencia las diferentes especificaciones. –

7

Aparentemente hay un método described_class.

https://www.relishapp.com/rspec/rspec-core/docs/metadata/described-class

supongo que es más limpio que subject.class, ya que no introduce otra llamada . método, lo que reduce la legibilidad.

El uso de described_class o subject.class puede ser más SECO que mencionar la clase explícitamente en cada ejemplo. Pero personalmente creo que no obtener el resaltado de sintaxis que viene al mencionar explícitamente el nombre de la clase es una lástima, y ​​creo que reduce la legibilidad, a pesar de ser totalmente ganador en el departamento de mantenimiento.

Una cuestión que se plantea en relación con las mejores prácticas:

¿Debe utilizar described_class siempre que sea posible dentro y fuera del método .expect(), o sólo dentro del método expect()?

+0

Esto es lo que prefiero usar en mis pruebas, dejando sujeto para los datos probados a través de dichos métodos. – DBrown

Cuestiones relacionadas