2010-09-28 33 views
15

Estoy usando la biblioteca mock escrita por Michael Foord para ayudar con mis pruebas en una aplicación django.¿Cómo burlarse de las llamadas a funciones encadenadas en python?

Me gustaría probar que estoy configurando mi consulta correctamente, pero no creo que deba llegar a la base de datos, así que estoy tratando de burlarme de la consulta.

Puedo burlar la primera parte de la consulta, pero no obtengo los resultados que me gustaría cuando encadenó cosas adicionales.

La función:

 
    @staticmethod 
    def get_policies(policy_holder, current_user): 
     if current_user.agency: 
      return Policy.objects.filter(policy_holder=policy_holder, version__agency=current_user.agency).distinct() 
     else: 
      return Policy.objects.filter(policy_holder=policy_holder) 

y mi prueba: pasa la primera afirmación, el segundo no.

 
    def should_get_policies_for_agent__user(self): 
     with mock.patch.object(policy_models.Policy, "objects") as query_mock: 
      user_mock = mock.Mock() 
      user_mock.agency = "1234" 
      policy_models.Policy.get_policies("policy_holder", user_mock) 
      self.assertEqual(query_mock.method_calls, [("filter",(), { 
       'policy_holder': "policy_holder", 
       'version__agency': user_mock.agency, 
      })]) 
      self.assertTrue(query_mock.distinct.called) 

estoy bastante seguro de que el problema es que el query_mock inicial está volviendo una nueva maqueta después de la .Filter() se llama, pero no saben cómo capturar esa nueva maqueta y asegúrese .distinct() fue llamado.

¿Hay alguna manera mejor de probar lo que trato de obtener? Estoy intentando asegurarme de que se está llamando a la consulta correcta.

+4

Por favor, no pierda el tiempo burlándose de las consultas de Django. Simplemente cree un "accesorio" y ejecute las consultas reales con los datos de su dispositivo. Es mucho más simple y produce resultados de prueba mucho más útiles. –

+0

Gracias por su comentario. Hemos estado utilizando accesorios, pero estamos tratando de alejarnos de ellos en ciertas instancias por dos razones. uno: nuestros modelos son complejos con muchas relaciones. la configuración de los accesorios para este caso particular necesitaría datos de dispositivos para usuarios, empresas, agencias, titulares de pólizas, políticas y versiones. No necesito ejecutar realmente la consulta, solo necesito asegurarme de que esté configurada correctamente. dos: nuestras pruebas se ejecutan mucho más lento usando los accesorios – Aaron

+0

@ Aaron: Hacemos esto. (1) ejecuta el administrador integrado para crear los datos. (2) hacer una dumpdata de las páginas de administración hechas a mano. Nuestros dispositivos son pequeños (docenas de filas como máximo), cargan muy rápido y nos ahorran tratando de burlarse de Django. –

Respuesta

15

Cada objeto falso se aferra al objeto simulado que devolvió cuando se lo llamó. Puede obtenerlo utilizando la propiedad return_value de su objeto simulado.

Para su ejemplo,

self.assertTrue(query_mock.distinct.called) 

distinta no fue llamado en su maqueta, se llamaba en el valor de retorno del método de filtro de la maqueta, por lo que se puede afirmar que fue llamado distinta al hacer esto :

self.assertTrue(query_mock.filter.return_value.distinct.called) 
+0

Tan simple ... Gracias por proporcionar una respuesta útil y clara. Mucho más útil que la broma de ida y vuelta entre usted y S.Lott ... – Aaron

Cuestiones relacionadas