estoy usando empezando a utilizar una pitón mock library para mi prueba. Quiero simular un módulo que se importa dentro del espacio de nombres del módulo bajo prueba sin realmente importarlo o exigir que exista primero (es decir, lanzar un ImportError).Python: Prototipo de un módulo sin importarlo o que necesitan que exista
Supongamos que existe el siguiente código:
foo.py
import helpers
def foo_func():
return helpers.helper_func()
El objetivo es poner a prueba foo_func() cuando 'helpers.py' no existe en ninguna parte, y si existe, acto como si no fuera así
primer intento, mediante el super cool decorador @patch:
from mock import patch, sentinel
import foo
@patch("foo.helpers")
def foo_test(mock):
mock.helper_func.return_value = sentinel.foobar
assert foo.foo_func() == sentinel.foobar
Esto funciona si el módulo de "ayudantes" se puede importar. Si no existe, obtengo un ImportError.
siguiente intento con el parche, sans decorador:
from mock import patch, sentinel, Mock
import foo
helpers_mock = patch("foo.helpers")
helpers_mock.start()
def foo_test():
helpers_mock.helper_func = Mock('helper_func')
helpers_mock.helper_func.return_value = sentinel.foobar
assert foo.foo_func() == sentinel.foobar
Una vez más, esto no funciona si "ayudantes" que falta ... y, si existe, la afirmación falla. No estoy muy seguro de por qué sucede eso.
tercer intento, solución actual:
import sys
helpers_mock = Mock(name="helpers_mock", spec=['helper_func'])
helpers_mock.__name__ = 'helpers'
sys.modules['helpers'] = helpers_mock
import foo
def foo_test():
helpers_mock.helper_func.return_value = sentinel.foobar
assert foo.foo_func() == sentinel.foobar
pasa esta prueba, independientemente de si existe o no "helpers.py".
¿Es esta la mejor manera de lograr este objetivo? ¿La biblioteca burlona que estoy usando ofrece una alternativa a esto? ¿De qué otra manera puedo hacer esto?
Mientras yo estoy a favor de prueba unitaria Creo que en este caso está probando una característica del lenguaje y no una función útil de su código. También puede corregir su importación en foo.py para que parte de este parche de mono no sea necesario con un guardia de importación (por ejemplo: try: import helpers excepto ImportError: helpers = None en foo.py en lugar de la importación bare). Me refiero a que ahora mismo foo.py no está escrito en a para permitir que falten los ayudantes y permitir eso debería simplificar enormemente tus pruebas. – stderr
Me gusta mucho la idea del protector de importación, resuelve muchos problemas. Si uso el protector de importación como sugiere, puedo usar el primer ejemplo que di (@patch decorator). ¡Gracias! –