Как смоделировать метод экземпляра в Python - PullRequest
0 голосов
/ 05 марта 2020

Рассмотрим следующие три файла.

# my_class.py

class MyClass:
    def __init__(self):
        pass

    def do_thing(self):
        return 5


# main.py

from my_class import MyClass

def my_func():
    instance = MyClass()
    instance.do_thing()


# test_main.py

from main import my_func
from unittest.mock import patch

@patch('main.MyClass')
def test_my_func(MockMyClass):
    my_func()
    MockMyClass.do_thing.assert_called_once()

AssertionError: Expected 'do_thing' to have been called once. Called 0 times.

Я создаю экземпляр класса MyClass внутри функции драйвера my_func и вызываю один из методов класса do_thing , Я хотел бы проверить, что при вызове функции драйвера метод класса вызывается ровно один раз. Я сталкиваюсь с ошибкой утверждения, которая вызывает у меня проблемы.

Я прочитал миллион и одну публикацию SO и другие ресурсы онлайн о Python издевательствах, но я не могу понять это. Я думал, что хитрость была в том, что декоратор @patch исправляет пространство имен, в которое импортируется модуль, а не из [Python Насмешка над функцией из импортированного модуля . Что я здесь не так делаю?

1 Ответ

0 голосов
/ 28 апреля 2020

Метод do_thing является методом экземпляра класса MyClass, NOT . Вы утверждаете, MockMyClass.do_thing.assert_called_once() не правильно. Вот решение для модульного тестирования:

my_class.py:

class MyClass:
    def __init__(self):
        pass

    def do_thing(self):
        return 5

main.py:


from my_class import MyClass


def my_func():
    instance = MyClass()
    instance.do_thing()

test_main.py:

from main import my_func
import unittest
from unittest.mock import patch


class TestMain(unittest.TestCase):
    @patch('main.MyClass')
    def test_my_func(self, MockMyClass):
        mock_my_class_instance = MockMyClass.return_value
        my_func()
        mock_my_class_instance.do_thing.assert_called_once()


if __name__ == '__main__':
    unittest.main()

Результаты модульных испытаний с отчетом о покрытии:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Name                                      Stmts   Miss  Cover   Missing
-----------------------------------------------------------------------
src/stackoverflow/60539392/main.py            4      0   100%
src/stackoverflow/60539392/my_class.py        5      2    60%   3, 6
src/stackoverflow/60539392/test_main.py      10      0   100%
-----------------------------------------------------------------------
TOTAL
...