El módulo Aincluye import Ben su parte superior. Sin embargo, bajo condiciones de prueba que me gustaría burlarse B de A(simulacro A.B) y abstenerse completamente de la importación B.
De hecho, Bno está instalado en el entorno de prueba a propósito.
Aes la unidad bajo prueba Tengo que importar Acon toda su funcionalidad. Bes el módulo que necesito burlarme. Pero ¿cómo puedo burlarse Bdentro Ay parada Ade la importación de los bienes B, si lo primero que Ahace es la importación B?
(La razón por la que B no está instalado es porque uso pypy para realizar pruebas rápidas y desafortunadamente B todavía no es compatible con pypy).
¿Como se puede hacer esto?
fuente

Mockno parcheará algunos atributos mágicos (__%s__) como__name__.sys.modules['B'] = Nonepero no parece funcionar.mocky luego llamarmock.Mock()El builtin
__import__se puede burlar con la biblioteca 'simulacro' para un mayor control:Decir
Aparece:A.a()devolucionesb_mock.func()que se pueden burlar también.Nota para Python 3: como se indica en el registro de cambios para 3.0 ,
__builtin__ahora se llamabuiltins:El código en esta respuesta funciona bien si lo reemplaza
__builtin__porbuiltinsPython 3.fuente
import_mockme llamen porimport A, pero no por nada que importe.ImportError: No module named '__builtin__'__builtin____builtin__porbuiltinspython3 ( docs.python.org/3/whatsnew/3.0.html?highlight=__builtin__ )Fácil, simplemente simula la biblioteca en sys.modules antes de que se importe:
y luego, siempre y cuando
Ano se base en tipos específicos de datos devueltos por los objetos de B:debería funcionar
También puedes burlarte de
import A.B:Esto funciona incluso si tiene submódulos, pero querrá burlarse de cada módulo. Digamos que tienes esto:
Para burlarse, simplemente haga lo siguiente antes de importar el módulo que contiene lo anterior:
(Mi experiencia: tenía una dependencia que funcionaba en una plataforma, Windows, pero no funcionaba en Linux, donde ejecutamos nuestras pruebas diarias. Así que necesitaba burlarme de la dependencia para nuestras pruebas. Por suerte era una caja negra, así que No necesitaba configurar mucha interacción).
Efectos secundarios burlones
Anexo: En realidad, necesitaba simular un efecto secundario que tomó algún tiempo. Así que necesitaba un método de objeto para dormir por un segundo. Eso funcionaría así:
Y luego el código tarda un tiempo en ejecutarse, al igual que el método real.
fuente
Me doy cuenta de que llego un poco tarde a la fiesta aquí, pero aquí hay una forma algo loca de automatizar esto con la
mockbiblioteca:(aquí hay un ejemplo de uso)
La razón por la que esto es tan ridículamente complicado es cuando se produce una importación, Python básicamente hace esto (por ejemplo
from herp.derp import foo)sys.modules['herp']? De lo contrario importalo. Si aun noImportErrorsys.modules['herp.derp']? De lo contrario importalo. Si aun noImportErrorfoodesys.modules['herp.derp']. MásImportErrorfoo = sys.modules['herp.derp'].fooHay algunas desventajas en esta solución pirateada: si algo más se basa en otras cosas en la ruta del módulo, este tipo de problemas lo arruina. Además, esto solo funciona para cosas que se importan en línea, como
o
fuente
La respuesta de Aaron Hall funciona para mí. Solo quiero mencionar una cosa importante,
si en
A.pyti lo hacesfrom B.C.D import Eentonces en
test.pydebe burlarse de cada módulo a lo largo del camino, de lo contrario obtendráImportErrorfuente
Encontré una buena manera de burlarse de las importaciones en Python. Aquí se encuentra la solución Zaadi de Eric que acabo de usar dentro de mi aplicación Django .
Tengo una clase
SeatInterfaceque es la interfaz para laSeatclase de modelo. Entonces dentro de miseat_interfacemódulo tengo una importación de este tipo:Quería crear pruebas aisladas para la
SeatInterfaceclase conSeatclase burlada comoFakeSeat. El problema era: cómo ejecutar las pruebas fuera de línea, donde la aplicación Django está inactiva. Tuve el siguiente error:La solución fue:
Y luego la prueba funciona mágicamente OK :)
fuente
Si haces un
import ModuleB, realmente estás llamando al método incorporado__import__como:Puede sobrescribir este método importando el
__builtin__módulo y hacer un contenedor alrededor del__builtin__.__import__método. O podrías jugar con elNullImportergancho delimpmódulo. Capturando la excepción y burlándose de su módulo / clase en elexceptbloque.Puntero a los documentos relevantes:
docs.python.org:
__import__Acceso a las partes internas de importación con el módulo imp
Espero que esto ayude. Se le recomienda encarecidamente que entre en los perímetros más arcanos de la programación de Python y que a) comprenda de manera sólida lo que realmente quiere lograr yb) comprenda a fondo las implicaciones es importante.
fuente