unittest.mock
:
mock_obj.called
: Проверяет, был ли вызван мок-объект хотя бы раз.mock_obj.assert_called()
: Проверяет, что мок-объект был вызван. Если не был, выбрасывает исключение AssertionError
.mock_obj.assert_called_once()
: Проверяет, что мок-объект был вызван ровно один раз.mock_obj.assert_called_with(*args, **kwargs)
: Проверяет, что мок-объект был вызван с указанными аргументами.mock_obj.assert_called_once_with(*args, **kwargs)
: Комбинация assert_called_once
и assert_called_with
.mock_obj.call_count
: Возвращает количество вызовов мок-объекта.mock_obj.call_args
: Хранит последние аргументы, с которыми был вызван мок.mock_obj.call_args_list
: Хранит список всех вызовов с аргументами.
from unittest.mock import Mock
mock_obj = Mock()
mock_obj.my_method(1, arg='value')
mock_obj.my_method.assert_called_with(1, arg='value')
Для проверки, был ли вызван метод на мок-объекте в Python, обычно используют библиотеку unittest.mock
(или mock
для Python 2).
Вот основные способы и примеры:
assert_called()
: Проверяет, был ли метод вызван хотя бы один раз.
import unittest
from unittest.mock import Mock
class MyTest(unittest.TestCase):
def test_method_called(self):
mock_obj = Mock()
mock_obj.my_method()
mock_obj.my_method.assert_called() # Утверждение, что метод был вызван
assert_not_called()
: Проверяет, что метод не был вызван.
import unittest
from unittest.mock import Mock
class MyTest(unittest.TestCase):
def test_method_not_called(self):
mock_obj = Mock()
#mock_obj.my_method() # Метод не вызывается
mock_obj.my_method.assert_not_called() # Утверждение, что метод не был вызван
assert_called_once()
: Проверяет, что метод был вызван ровно один раз.
import unittest
from unittest.mock import Mock
class MyTest(unittest.TestCase):
def test_method_called_once(self):
mock_obj = Mock()
mock_obj.my_method()
mock_obj.my_method.assert_called_once() # Утверждение, что метод был вызван один раз
assert_called_with(*args, **kwargs)
: Проверяет, что метод был вызван с определенными аргументами.
import unittest
from unittest.mock import Mock
class MyTest(unittest.TestCase):
def test_method_called_with(self):
mock_obj = Mock()
mock_obj.my_method(1, "hello", arg2=True)
mock_obj.my_method.assert_called_with(1, "hello", arg2=True) # Утверждение о вызове с аргументами
assert_called_once_with(*args, **kwargs)
: Проверяет, что метод был вызван ровно один раз с определенными аргументами.
import unittest
from unittest.mock import Mock
class MyTest(unittest.TestCase):
def test_method_called_once_with(self):
mock_obj = Mock()
mock_obj.my_method(1, "hello", arg2=True)
mock_obj.my_method.assert_called_once_with(1, "hello", arg2=True) # Утверждение о вызове один раз с аргументами
assert_any_call(*args, **kwargs)
: Проверяет, что метод был вызван хотя бы один раз с указанными аргументами (не обязательно последним вызовом).
import unittest
from unittest.mock import Mock, call
class MyTest(unittest.TestCase):
def test_method_any_call(self):
mock_obj = Mock()
mock_obj.my_method(1)
mock_obj.my_method(2)
mock_obj.my_method.assert_any_call(2) # Утверждение, что был вызов с аргументом 2 (не обязательно последний)
assert_has_calls(calls)
: Проверяет, что метод был вызван с определенной последовательностью вызовов. Порядок важен.
import unittest
from unittest.mock import Mock, call
class MyTest(unittest.TestCase):
def test_method_has_calls(self):
mock_obj = Mock()
mock_obj.my_method(1)
mock_obj.my_method(2)
calls = [call(1), call(2)]
mock_obj.my_method.assert_has_calls(calls) # Утверждение о последовательности вызовов
mock_calls
: Это атрибут, который содержит список всех вызовов метода. Его можно использовать для более гибких проверок, особенно если стандартных `assert` методов недостаточно.
import unittest
from unittest.mock import Mock, call
class MyTest(unittest.TestCase):
def test_method_mock_calls(self):
mock_obj = Mock()
mock_obj.my_method(1)
mock_obj.my_method(2, arg="value")
expected_calls = [call.my_method(1), call.my_method(2, arg="value")]
self.assertEqual(mock_obj.mock_calls, expected_calls)
Важно: Убедитесь, что вы импортировали unittest
, если используете unittest.TestCase
для тестов.
Пример полного тестового класса:
import unittest
from unittest.mock import Mock
class MyClass:
def do_something(self, a, b):
return a + b
def another_method(self):
pass
class TestMyClass(unittest.TestCase):
def test_do_something(self):
# Mock MyClass
my_obj = Mock(spec=MyClass) # Лучше использовать spec для типобезопасности
# Configure the mock to return a specific value
my_obj.do_something.return_value = 5
# Call the method (or a function that uses the method)
result = my_obj.do_something(2, 3)
# Assert that the method was called with the correct arguments
my_obj.do_something.assert_called_with(2, 3)
# Assert that the method was called once
my_obj.do_something.assert_called_once()
# Assert the return value
self.assertEqual(result, 5)
def test_another_method(self):
my_obj = Mock(spec=MyClass)
my_obj.another_method()
my_obj.another_method.assert_called()
my_obj.another_method.assert_called_once()
if __name__ == '__main__':
unittest.main()
Рекомендации:
spec
при создании моков, чтобы убедиться, что мок-объект имеет те же атрибуты и методы, что и настоящий объект. Это улучшает типобезопасность и помогает избежать ошибок, связанных с опечатками в именах методов.pytest
(с плагином pytest-mock
) для более лаконичного синтаксиса и дополнительных возможностей мокирования.