Usando Mock Objects en Rails
Publicado por Edgar González 6 Diciembre 2005 en Rails, How To's, Testing. Etiquetas: No Tags. english • españolEl ejemplo frecuente que se utiliza para mostrar el beneficio de usar Mock Objects durante el testing de nuestro software, es el caso en el que la aplicación que estamos desarrollando depende de un ente externo que no está disponible durante la fase de desarrollo/testing, por ejemplo nuestro software debe interactuar con un ERP (SAP, Baan, etc), y no tenemos el ERP a nuestra disposición. En este caso lo que se hace es crear un mock object que reemplaza el ERP (a momento de testing) , para poder probar asi la funcionalidad de nuestro software.
A pesar de que el ejemplo "frecuente" es válido, hay situaciones más comúnes que tambien justifican el uso de mock objects.
Supongamos que nuestro software es una aplicación Web (hecha en RubyOnRails) que tiene la funcionalidad de autenticar un usuario vía un cookie (remember-me feature), y que dicho cookie tiene una fecha de expiración, despues de la cual no es válido para autenticar un usuario en nuestra aplicación.
Dado esto se quiere probar que la expiración del cookie efectivamente funcione (del lado de nuestra aplicación, no del lado del browser). Es decir, tenemos que simular el paso del tiempo (para alcanzar que la fecha de expiración)
Para este functional test tenemos los siguientes archivos: /test/functional/user_controller_test.rb (suponiendo que el controller encargado de la autenticación es el user_controller.rb) y /test/mocks/test/timer.rb
Nuestro /test/functional/user_controller_test.rb sería algo de este estilo:
require 'user_controller'
# Re-raise errors caught by the controller.
class UserController; def rescue_action(e) raise e end; end
class UserControllerTest <Test::Unit::TestCase
fixtures :users
def setup
@controller = UserController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_login_cookie_expired
# go to a secure page with a valid value cookie but already expired
@request.cookies['remember'] = CGI::Cookie.new('remember', 'valid_value')
Time.advance_by_days = APP_CONFIG[:cookie_login_expires]
get :secure_page
assert_redirected_to :action => 'login'
Time.advance_by_days = 0
end
end
El final del método test_login_cookie_expired es el que hace la prueba de la expiración del cookie, para esto lo que hacemos es modificar la clase Time, en particular el método now y le agregamos el atributo advance_by_days a la clase (no a las instancias), vía un mock object (/test/mocks/test/timer.rb) para lograr simular el "avance del tiempo".
Time.class_eval {
@@advance_by_days = 0
cattr_accessor :advance_by_days
class << Time
#> Este alias permite conservar el método original
alias now_old now
#> Aquí se redefine el método "now"
def now
if Time.advance_by_days != 0
return Time.at(now_old.to_i + Time.advance_by_days * 60 * 60 * 24 + 1)
else
now_old
end
end
end
}
El archivo /test/mocks/test/timer.rb sería:
Esta modificación a la clase Time funciona (y en general los mock objects), porque Rails modifica el search path para incluir de primero el path de los mocks ( /test/mocks/test ).
La idea de modificar la clase Time fue tomada del SaltedHashLoginGenerator
"A language that doesn't affect the way you think about programming, is not worth knowing."
Alan J. Perlis
0 Respuestas a “Usando Mock Objects en Rails”
Por favor Espera
Añade un Comentario