Estoy usando Python 3.8 y pytest 6.0.1. Tengo esta clase

class MyHelperService:
    def __init__(self, args):
        ...

    def my_method1(self):
        ... logic here ...  

Luego, en otra clase, invoco el método anterior.

def main(req: func.HttpRequest) -> func.HttpResponse:
        ...
                sb = MyHelperService(args)
                sb.my_method1()

¿Cómo, en pytest, me burlo de "my_method1" para poder probar que fue llamado sin necesariamente ejecutar toda la lógica dentro de él?

def test_run_it():
    ...
    resp = _import.main(req)
0
Dave 28 ago. 2020 a las 17:48

1 respuesta

La mejor respuesta

Suponiendo que MyHelperService vive en my_project/my_helper_service.py y main en my_project/main.py, y suponiendo que en main importa la clase como:

from my_project.my_helper_service import MyHelperService

Puede parchear su método de esta manera (supongo que usa otro accesorio my_fixture según los comentarios):

from unittest import mock

@mock.patch("my_project.main.MyHelperService.my_method1")
def test_run_it(method1_mock, my_fixture):
    ...
    resp = _import.main(req)
    method1_mock.assert_called_once()

Esto reemplaza method1 por un simulacro que solo registra todas las llamadas sin ejecutar el código original. Tenga en cuenta que los argumentos simulados son argumentos posicionales y, por lo tanto, la mayoría son los primeros argumentos, mientras que los argumentos fixture son argumentos de palabras clave (que deben ubicarse después de los argumentos posicionales).

Alternativamente, puede usar la versión del administrador de contexto:

def test_run_it(my_fixture):
    ...
    with mock.patch("my_project.main.MyHelperService.my_method1") as method1_mock:
        resp = _import.main(req)
        method1_mock.assert_called_once()

O la versión mocker, si ha instalado pytest-mock:

def test_run_it(mocker, my_fixture):
    ...
    method1_mock = mocker.patch("my_project.main.MyHelperService.my_method1")
    resp = _import.main(req)
    method1_mock.assert_called_once()

Algunos enlaces útiles:

0
MrBean Bremen 2 sep. 2020 a las 18:06