¿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?filese ha ido!mock_openes parte delmockframework y es muy simple de usar.patchusado como contexto devuelve el objeto usado para reemplazar el parcheado: puede usarlo para simplificar su prueba.Python 3.x
Usar en
builtinslugar de__builtin__.Python 2.7
mockno es parteunittesty debes parchear__builtin__Estuche decorador
Si
patchusarías como decorador usandomock_open()el resultado comonewpatchargumento, puede ser un poco extraño.En este caso, es mejor usar el
new_callablepatchargumento de 's y recordar que cada argumento adicional quepatchno use se pasará anew_callablefuncionar como se describe en lapatchdocumentación .Por ejemplo, la versión decorada para Python 3.x es:
Recuerde que en este caso
patchagregará 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_valuedemock_openen otro objeto simulado y afirmar el segundo simulacroreturn_value), pero funcionó agregandomock_opencomonew_callable.sixmódulo para tener unmockmódulo consistente . Pero no sé si se asigna tambiénbuiltinsen un módulo común.Con las últimas versiones de simulacro, puede usar el ayudante realmente útil mock_open :
fuente
.writellamadas?handle.write.assert_any_call(). También puede usarhandle.write.call_args_listpara 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_listes más seguro que llamar a cualquiera de losMock.assert_xxxmé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_filecaso; 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 )
fenas ffunción de los argumentos pasados,open()aquí hay una forma de hacerlo:Básicamente,
open()devolverá un objeto ywithllamará__enter__()a ese objeto.Para burlarse correctamente, debemos burlarnos
open()para devolver un objeto simulado. Ese objeto simulado debe simular la__enter__()llamada (MagicMockhará 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_datamétodo.Pasé un archivo simulado completo como una cadena
open()y mido_something_with_dataaspecto 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é
opena otro módulo sin tener que crear un nuevo archivo.prueba.py
MyObj.py
Al parchear la
openfunció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