Модульный тест Python Имитирует импорт и проверяет утверждение, вызываемое с помощью

#python #unit-testing #magicmock

Вопрос:

У меня есть класс ProductionClass с методом method_to_test , который я хочу протестировать. У класса ProductionClass есть зависимость api , над которой я хочу посмеяться в тесте.

 from my_module.apis import api
class ProductionClass:
     def method_to_test:
         data = api.method_to_mock()
         api.method_to_check_call(data)
 

Код теста выглядит следующим образом:
Потому api что у меня есть макет класса MockApi , который я использую, обращаясь к нему в @patch декораторе.

 from unittest.mock import patch, MagicMock

class MockApi:
    def method_to_mock():
        return some_mock_data
    def method_to_check_call(data):
        pass

class TestClass:
    @patch('my_module.apis.api', MagicMock(return_value=MockApi()))
    def test_check_called_with(self):
         from module_of_class_production_class.ProductionClass import method_to_test
         mock_api = MockApi()
         method_to_test()
         some_data = { ... }
         mock.method_to_check_call.assert_called_with(some_data)
         
 

Проблема в том, что он не работает, потому mock_api что не является тем же экземпляром MockApi , который предусмотрен в @patch декораторе. Есть ли лучший способ проверить это?

Ответ №1:

Я не проверял это, но я думаю, что ваш объект patch будет передан в качестве первого аргумента, чтобы test_check_called_with так:

 @patch('my_module.apis.api', MagicMock(return_value=MockApi()))
def test_check_called_with(self, your_magic_mock):
    # Rest of code
 

Вы также можете использовать with конструкцию следующим образом:

 def test_check_called_with(self):
    my_api = MockApi()
    with patch('my_module.apis.api', MagicMock(return_value=my_api)) as my_mock_api:
        # Your code here
 

Вы можете ознакомиться с официальной документацией python здесь для получения более подробной информации: https://docs.python.org/3/library/unittest.mock.html#quick-guide