2010-01-08 9 views
10

En una prueba funcional de mi aplicación Rails, quiero probar dónde me redirigen. La URL esperada apunta a un recurso externo (eso significa que no es parte de mi aplicación).¿Cómo puedo probar solo una parte de la URL a la que me redirigen (usando assert_redirected_to)?

La URL tiene el siguiente aspecto:. https://my.url.com/foo?bar1=xyz&bar2=123

Por desgracia, no se puede predecir los parámetros, ya que son generados por un recurso externo *
Sin embargo, el resto de la URL mantiene siempre la misma: https://my.url.com/foo

Normalmente utilizo assert_redirected_to para este tipo de prueba, pero esto espera toda la URL, incluidos los parámetros.

¿Alguien puede pensar en otra forma de probar esa redirección pero solo verificar la primera parte de la URL sin los parámetros?

(la URL no está en la assigns Hash)

* (hago una llamada a la API a una solicitud, que las respuestas con la URL me redirect_to)

Respuesta

15

Los comandos de solicitud HTTP como post, etc. get crear una variable de instancia llamada @response cuando se les llama *. @response contiene un método llamado redirect_url que almacena la URL a la que se le ha redirigido (en caso de que realmente haya sido redirigido).

para ello, sólo puede utilizar una normal de assert_match para comparar una expresión regular para @response.redirect_url:

post :my_action_to_test 
assert_response :redirect 
assert_match /https:\/\/my.url.com\/foo/, @response.redirect_url 

* (de hecho, estos métodos HTTP sólo tiene que utilizar el método privado process, que crea la variable @response).

+2

Para la posteridad: puede usar '% r {https://my.url.com/foo}' para construir la expresión regular sin tener que escapar de las barras diagonales. –

2

Dos pensamientos rápidos sobre esto:

1) Si su prueba funcional realmente se conecta a la aplicación externa, ¿por qué no simplemente saca los parámetros como lo haría normalmente y prueba que la redirección se produce correctamente?

2) Si su prueba funcional no se conecta a la aplicación externa, entonces la está fingiendo de todos modos, así que me saltaría la prueba de la URL de redireccionamiento y solo probaré una redirección con assert_response: redirigir. O bien, cree un simulacro que devuelva la URL para redireccionar como si fuera la aplicación externa, pero hágalo de forma tal que pueda obtener los parámetros de la misma.

Dicho esto, no te dejes llevar por pruebas que sientes que tienes que cubrir todos los escenarios posibles.

+0

Gracias por su opinión. Probablemente tengas razón, no debería dejarme llevar demasiado por las pruebas. Creo que en mi caso, realmente no es importante que pruebe la URL correcta que me redireccionaron. Sin embargo, tenía curiosidad, si es posible resolver este problema. –

1

¿Qué tal esto? Envuelve assert_redirected_to para permitir un Regexp como primer argumento. Sin embargo, esto no funcionará si intenta hacer coincidir el Regexp con un Hash; solo un String. Hacer eso requeriría un poco más de trabajo.

ActionController::TestCase.class_eval do 

    old_assert_redirected_to = method(:assert_redirected_to) 

    define_method(:assert_redirected_to) do |*args| 
    if args.[0].kind_of?(Regexp) 
     assert_response(:redirect, args[1]) 
     assert args[0] === @response.redirected_to 
    else 
     old_assert_redirected_to.bind(self).call(*args) 
    end 
    end 

end 
+0

+1 por señalarme en la dirección correcta. Tu respuesta me ayudó a encontrar mi propia respuesta. :-) ¡Gracias! –

0

Uso el siguiente método para ignorar cualquier parámetro de cadena de consulta.Se basa en la implementación oficial de assert_redirected_to

# ignores any query string params eg. notice or alert messages for flash 
def custom_assert_redirected_to(path) 
    assert_response :redirect 

    if path === Regexp 
    url = path 
    else 
    url = ActionController::Redirecting._compute_redirect_to_location(@request, path) 
    end 

    assert_equal url, @response.location.split("?").first 
end 
Cuestiones relacionadas