2010-05-16 11 views
13

Estoy escribiendo un rubygem que pueden elevar una ArgumentError si los argumentos proporcionados a su método único no son válidos. ¿Cómo puedo escribir una prueba para esto usando RSpec?¿Cómo probar que los argumentos inválidos generan una excepción ArgumentError usando RSpec?

El ejemplo siguiente muestra el tipo de aplicación que tengo en mente. El método bar espera que un solo argumento booleano (:baz), del tipo de los que se comprueba para asegurarse de que lo que realmente es un valor lógico:

module Foo 
    def self.bar(options = {}) 
    baz = options.fetch(:baz, true) 
    validate_arguments(baz) 
    end 

    private 
    def self.validate_arguments(baz) 
    raise(ArgumentError, ":baz must be a boolean") unless valid_baz?(baz) 
    end 

    def self.valid_baz?(baz) 
    baz.is_a?(TrueClass) || baz.is_a?(FalseClass) 
    end 
end 

Respuesta

28

que usar algo similar a lo que JHurra colocado:.

it "should raise ArgumentError for arguments that are not boolean" do 
    expect{ Foo.validate_arguments(nil) }.to raise_error(ArgumentError) 
end 

No hay necesidad de alias (rspec 1.3)

+0

Gracias. ¿RSpec automáticamente tiene acceso a métodos privados? Mi método 'validate_arguments' es privado. –

+6

El método no es privado porque es un método de clase y la palabra clave privada solo se aplica a métodos de instancia. Cree los métodos de instancia de métodos o use 'private_class_method: mymethodname' para hacer que los métodos de clase sean privados. – Ragmaanir

+0

No lo sabía, gracias. –

3
it "should raise ArgumentError for arguments that are not boolean" do 
    lambda{ Foo.validate_arguments(something_non_boolean) }.should raise_error(ArgumentError) 
end 
+0

. . Gracias he editado la pregunta original porque se me olvidó indicar que el 'validate_arguments' y' 'valid_baz métodos son privadas Así que estoy haciendo' lambda {Foo.bar (: baz => 'a')}?. . RAISE_ERROR .Should (ArgumentError) 'que pasa Sin embargo, la prueba todavía pasa si fijo':? baz' a un valor lógico en la prueba - cualquier idea de por qué me gusta –

+4

'col ias: running: lambda' en my 'spec_helper.rb' para que pueda escribir' running {...} .should raise_error'. – Theo

+0

@Theo Esa es una buena idea. –

2

A menos que sea muy importante que usted lanza una excepción para no valores booleanos, yo creo que sería más elegante para coaccionar el valor a un valor lógico, por ejemplo, con !!:

baz = !! options.fetch(:baz, true) 

de esta manera el código de cliente puede pasar cualquier valor Truthy o Falsy, pero todavía se puede estar seguro de que el valor yo con que trabajas es un booleano apropiado. También puede utilizar el operador ternario (por ejemplo baz = options.fetch(:baz, true) ? true : false si siente que !! es claro

+0

tomo su punto, pero mi método 'validate_arguments' realidad también valida otros argumentos que se pasan al método, usando la lógica de validación más complejo. –

+0

justo lo suficiente ... pero lo uso para los booleanos, es molesto para usar código que comprueba los tipos en un lenguaje dinámico. – Theo

Cuestiones relacionadas