¿Cómo pruebo el siguiente código con simulacros (utilizando simulacros, el decorador de parches y los centinelas proporcionados por el marco simulado de Michael Foord ):
def testme(filepath):
with open(filepath, 'r') as f:
return f.read()
python
mocking
with-statement
Daryl Spitzer
fuente
fuente
Respuestas:
La forma de hacer esto ha cambiado en simulacro 0.7.0 que finalmente admite burlarse de los métodos de protocolo de Python (métodos mágicos), particularmente usando MagicMock:
http://www.voidspace.org.uk/python/mock/magicmock.html
Un ejemplo de simulacro abierto como administrador de contexto (de la página de ejemplos en la documentación simulada):
fuente
__enter__
y también se__exit__
burla de los objetos: ¿este último enfoque está desactualizado o sigue siendo útil?file
se ha ido!mock_open
es parte delmock
framework y es muy simple de usar.patch
usado como contexto devuelve el objeto usado para reemplazar el parcheado: puede usarlo para simplificar su prueba.Python 3.x
Usar en
builtins
lugar de__builtin__
.Python 2.7
mock
no es parteunittest
y debes parchear__builtin__
Estuche decorador
Si
patch
usarías como decorador usandomock_open()
el resultado comonew
patch
argumento, puede ser un poco extraño.En este caso, es mejor usar el
new_callable
patch
argumento de 's y recordar que cada argumento adicional quepatch
no use se pasará anew_callable
funcionar como se describe en lapatch
documentación .Por ejemplo, la versión decorada para Python 3.x es:
Recuerde que en este caso
patch
agregará el objeto simulado como argumento de su función de prueba.fuente
with patch("builtins.open", mock_open(read_data="data")) as mock_file:
puede convertir en sintaxis decoradora? Lo he intentado, pero no estoy seguro de lo que necesito pasar@patch("builtins.open", ...)
como segundo argumento.return_value
demock_open
en otro objeto simulado y afirmar el segundo simulacroreturn_value
), pero funcionó agregandomock_open
comonew_callable
.six
módulo para tener unmock
módulo consistente . Pero no sé si se asigna tambiénbuiltins
en un módulo común.Con las últimas versiones de simulacro, puede usar el ayudante realmente útil mock_open :
fuente
.write
llamadas?handle.write.assert_any_call()
. También puede usarhandle.write.call_args_list
para recibir cada llamada si el pedido es importante.m.return_value.write.assert_called_once_with('some stuff')
es mejor imo. Evita registrar una llamada.Mock.call_args_list
es más seguro que llamar a cualquiera de losMock.assert_xxx
métodos. Si deletrea mal alguno de estos últimos, siendo atributos de Mock, siempre pasarán en silencio.Para usar mock_open para un archivo simple
read()
(el fragmento original de mock_open ya proporcionado en esta página está más orientado a la escritura):Tenga en cuenta según los documentos para mock_open, esto es específicamente para
read()
, por lo que no funcionará con patrones comunes comofor line in f
, por ejemplo.Utiliza python 2.6.6 / simulacro 1.0.1
fuente
for line in opened_file:
tipo de código. Intenté experimentar con StringIO iterable que implementa__iter__
y usar eso en lugar demy_text
, pero no tuve suerte.read()
que no funcione en sufor line in opened_file
caso; He editado la publicación para aclararfor line in f:
soporte de @EvgeniiPuchkaryov se puede lograr burlándose del valor de retornoopen()
como un objeto StringIO .with open("any_string") as f: print f.read()
La respuesta principal es útil, pero la amplié un poco.
Si desea establecer el valor de su objeto de archivo (la entrada )
f
enas f
función de los argumentos pasados,open()
aquí hay una forma de hacerlo:Básicamente,
open()
devolverá un objeto ywith
llamará__enter__()
a ese objeto.Para burlarse correctamente, debemos burlarnos
open()
para devolver un objeto simulado. Ese objeto simulado debe simular la__enter__()
llamada (MagicMock
hará esto por nosotros) para devolver el objeto simulado de datos / archivo que queremos (por lo tantomm.__enter__.return_value
). Hacer esto con 2 simulacros de la manera anterior nos permite capturar los argumentos pasadosopen()
y pasarlos a nuestrodo_something_with_data
método.Pasé un archivo simulado completo como una cadena
open()
y mido_something_with_data
aspecto era el siguiente:Esto transforma la cadena en una lista para que pueda hacer lo siguiente como lo haría con un archivo normal:
fuente
__enter__
? Definitivamente parece más un truco que una forma recomendada.Puede que llegue un poco tarde al juego, pero esto funcionó cuando llamé
open
a otro módulo sin tener que crear un nuevo archivo.prueba.py
MyObj.py
Al parchear la
open
función dentro del__builtin__
módulo a mimock_open()
, puedo simular escribir en un archivo sin crear uno.Nota: Si está utilizando un módulo que usa cython, o si su programa depende de cython de alguna manera, deberá importar el
__builtin__
módulo de cython al incluirloimport __builtin__
en la parte superior de su archivo. No podrá burlarse de lo universal__builtin__
si está utilizando cython.fuente
import __builtin__
a mi módulo de prueba. Este artículo ayudó a aclarar por qué esta técnica funciona tan bien como lo hace: ichimonji10.name/blog/6Para parchear la función incorporada open () con unittest:
Esto funcionó para un parche para leer una configuración json.
El objeto burlado es el objeto io.TextIOWrapper devuelto por la función open ()
fuente
Si no necesita más archivos, puede decorar el método de prueba:
fuente