rails help guias basics ruby-on-rails testing integration integration-testing rack

ruby-on-rails - help - ruby rack 2



Hacer que Rails realice pruebas de Rack middleware fuera de la cadena interna de Rails (2)

Contexto : una aplicación utiliza una parte de middleware de Rack que debe configurarse en config.ru, en lugar de la cadena de Middleware interna de Rails. Esto es por razones que no son relevantes para esta pregunta.

Pregunta : ¿Cómo hago que mis pruebas (funcionales e integración) estén al tanto de este middleware?

Voy a elaborar con un ejemplo. Vamos a crear una aplicación de Rails 3 prístina, utilizando rack-rewrite en rack-rewrite para propósitos de ilustración.

# /config/initializers/example.rb Rails.application.middleware.insert 0, ''Rack::Rewrite'' do r301 ''/so'', ''http://stackoverflow.com'' end # /test/integration/the_test.rb require ''test_helper'' class TheTest < ActionDispatch::IntegrationTest test "redirect from /so to http://stackoverflow.com" do get ''/so'' assert_redirected_to ''http://stackoverflow.com'' end end

Si ejecuta la prueba anterior, todo está bien, y con el navegador puede confirmar que visitar la ruta /so redireccionará a StackOverflow.

Genial, ahora configuremos esto fuera de Rails entonces. Elimine el archivo /config/initializers/example.rb descrito anteriormente, y cambie config.ru a lo siguiente:

# /config.ru require ::File.expand_path(''../config/environment'', __FILE__) map ''/so'' do run Rack::Rewrite do r301 '''', ''http://stackoverflow.com'' end end map ''/'' do run Deleteme::Application end

Ahora, la prueba dejará de funcionar. La funcionalidad funciona, como lo demuestra si visita /so con su navegador. Es solo que las pruebas no son conscientes de esa configuración de Rack.


(Gracias, Dan Croak, por haberme puesto en el camino correcto. Esta respuesta completa lo que dijo).

Respuesta corta

No se puede hacer para pruebas funcionales.

Para las pruebas de integración, agregue lo siguiente a su test_helper.rb:

ActionDispatch::IntegrationTest.app = Rack::Builder.new do eval File.read(Rails.root.join(''config.ru'')) end

Respuesta larga

Las pruebas funcionales son solo pruebas unitarias ejecutadas contra controladores. Cuando dice, por ejemplo, get :index , no está resolviendo una ruta. En su lugar, esta es una abreviatura para llamar al método de index , con un entorno de solicitud que incluye una mención al método HTTP que es GET.

Por lo tanto, tiene sentido que su pila Rack no influya en las pruebas funcionales.

Las pruebas de integración son una cuestión diferente. Está probando su pila completa allí, por lo que también querrá probar su middleware de Rack. El único problema es que, de forma predeterminada, estas pruebas solo ven los middlewares que agrega utilizando la propia API de Rails.

Pero digo "por defecto" porque Rails ofrece una manera de cambiar lo que se probará en Rack stack. De forma predeterminada, las pruebas de integración llaman a Rails.application para sus solicitudes. Puede cambiar esto a cualquier cosa que se adapte a sus necesidades.

Al utilizar el código anterior, usamos Rack::Builder crear una aplicación de Rack ad-hoc. Dentro del bloque, puede poner cualquier código que normalmente pondría dentro de un archivo config.ru . Para evitar la duplicación de código, eval carga nuestro archivo config.ru . Ahora nuestras pruebas de integración cargarán exactamente la misma aplicación que exponen nuestros servidores de aplicaciones.


Creo que el problema es que ActionDispatch::IntegrationTest usa su aplicación Rails.application como su aplicación Rack para la prueba.

Entonces, si puede ajustar esa regla de Rack::Rewrite en algún middleware de Rack, debería poder anular la aplicación de Rack que está probando en su prueba con:

ActionDispatch::IntegrationTest.app = MyRewriteMiddleware