2011-09-17 20 views
10

Estoy tratando de probar un controlador con webapp2 y me encuentro con lo que tiene que ser un pequeño error estúpido.¿Cómo obtener uri_for con webapp2 en prueba unitaria?

Me gustaría ser capaz de utilizar webapp2.uri_for en la prueba, pero me parece que no puede hacer eso:

def test_returns_200_on_home_page(self): 
     response = main.app.get_response(webapp2.uri_for('index')) 
     self.assertEqual(200, response.status_int) 

Si acabo de hacer main.app.get_response('/') funciona muy bien.

La excepción recibida es:

Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 318, in run 
    testMethod() 
    File "tests.py", line 27, in test_returns_200_on_home_page 
    webapp2.uri_for('index') 
    File "/Users/.../webapp2_example/lib/webapp2.py", line 1671, in uri_for 
    return request.app.router.build(request, _name, args, kwargs) 
    File "/Users/.../webapp2_example/lib/webapp2_extras/local.py", line 173, in __getattr__ 
    return getattr(self._get_current_object(), name) 
    File "/Users/.../webapp2_example/lib/webapp2_extras/local.py", line 136, in _get_current_object 
    raise RuntimeError('no object bound to %s' % self.__name__) 
RuntimeError: no object bound to request 

¿Hay alguna configuración tonta que me falta?

Respuesta

14

Creo que la única opción es establecer una solicitud falsa sólo para ser capaz de crear URIs para el examen:

def test_returns_200_on_home_page(self): 
    // Set a dummy request just to be able to use uri_for(). 
    req = webapp2.Request.blank('/') 
    req.app = main.app 
    main.app.set_globals(app=main.app, request=req) 

    response = main.app.get_response(webapp2.uri_for('index')) 
    self.assertEqual(200, response.status_int) 

Nunca use set_globals() exterior de pruebas. Es llamado por la aplicación WSGI para configurar la aplicación activa y la solicitud de una manera segura para subprocesos.

+0

Gracias por la respuesta @moraes. Lo intentaré cuando llegue a casa del trabajo. Realmente me gusta webapp2 por cierto, ¡gracias por compartirlo con nosotros! – Aaron

+0

Eso tampoco parece serlo. ahora recibo: Archivo "/Users/.../webapp2_example/lib/webapp2.py", línea 1671, en uri_for return request.app.router.build (request, _name, args, kwargs) AttributeError: 'NoneType 'objeto no tiene atributo' enrutador ' – Aaron

+0

De hecho, no es tan fácil. Corregí el fragmento; Espero que funcione ahora. – moraes

0

webapp2.uri_for() supone que se encuentra en un contexto de solicitud web y falla porque no puede encontrar el objeto request.

En lugar de solucionar esto, podría pensar en su aplicación como una caja negra y llamarla usando URI literales, como '/' como usted lo menciona. Después de todo, desea simular una solicitud web normal, y un navegador web también utilizará URI y no accesos directos de enrutamiento interno.

+0

Veo su punto, sin embargo, viola el principio 'DRY' para poner la url completa en cualquier lugar más de una vez. Si la URL cambia, es mucho más molesto (y propenso a errores) cambiar en todas partes a la que se hace referencia literal en lugar de cambiar la declaración de la ruta de la url y de hacerse. – Aaron

+0

De hecho, https://webapp-improved.appspot.com/guide /routing.html#extended-routes señala que DRY es parte de la motivación para mejorar webapp, "evitar los URI codificados en el código y las plantillas de la aplicación" – Pat

Cuestiones relacionadas