Исправьте метод одного класса в модульном тестировании и подтвердите, что он вызывается один раз - PullRequest
0 голосов
/ 18 июня 2020

Как вы исправляете метод в классе, а затем утверждаете, что этот исправленный метод был вызван только один раз?

Например:

import typing
import unittest
import unittest.mock

class Example:
    def __init__(self: "Example") -> None:
        self._loaded : bool = False
        self._data : typing.Union[str,None] = None

    def data(self: "Example") -> str:
        if not self._loaded:
            self.load()
        return self._data

    def load(self: "Example") -> None:
        self._loaded = True
        # some expensive computations
        self._data = "real_data"

def mocked_load(self: "Example") -> None:
    # mock the side effects of load without the expensive computation.
    self._loaded = True
    self._data = "test_data"

class TestExample( unittest.TestCase ):
    def test_load(self: "TestExample") -> None:
        # tests for the expensive computations
        ...

    @unittest.mock.patch("__main__.Example.load", new=mocked_load)
    def test_data(
        self: "TestExample",
        # patched_mocked_load: unittest.mock.Mock
    ) -> None:
        example = Example()
        data1 = example.data()
        self.assertEqual(data1, "test_data")
        # example.load.assert_called_once()
        # Example.load.assert_called_once()
        # mocked_load.assert_called_once()
        # patched_mocked_load.assert_called_once()

        data2 = example.data()
        self.assertEqual(data2, "test_data")
        # Should still only have loaded once.
        # example.load.assert_called_once()
        # Example.load.assert_called_once()
        # mocked_load.assert_called_once()
        # patched_mocked_load.assert_called_once()

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

Как в модульном тесте test_data утверждать, что исправленная функция load вызывалась только один раз?

1 Ответ

1 голос
/ 18 июня 2020

Проблема в том, что вы заменяете load своей собственной функцией, которая не является имитацией и, следовательно, не имеет методов assert_called_xxx.
Вам нужно заменить ее на макет и добавить желаемое поведение в вместо этого имитируйте:

    @unittest.mock.patch("__main__.Example.load")
    def test_data(
            self: "TestExample",
            patched_mocked_load: unittest.mock.Mock
    ) -> None:
        example = Example()
        patched_mocked_load.side_effect = lambda: mocked_load(example)
        data1 = example.data()
        self.assertEqual(data1, "test_data")
        patched_mocked_load.assert_called_once()

        data2 = example.data()
        self.assertEqual(data2, "test_data")
        patched_mocked_load.assert_called_once()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...