Это немного многословно, но я бы сделал что-то вроде этого (я предположил, что вы сохранили функцию my_function в файл с именем patch_one.py):
import patch_one # this is the file with my_function in it
from unittest.mock import patch
from unittest import TestCase
class MyTestCase(TestCase):
def test_my_function(self):
# because you used "with open(...) as f", we need a mock context
class MyContext:
def __enter__(self, *args, **kwargs):
return [1, 2] # note the two items
def __exit__(self, *args, **kwargs):
return None
# in case we want to know the arguments to open()
open_args = None
def f(*args, **kwargs):
def my_open(*args, **kwargs):
nonlocal open_args
open_args = args
return MyContext()
return my_open
# patch the gzip.open in our file under test
with patch('patch_one.gzip.open', new_callable=f):
# finally, we can call the function we want to test
ret_val = patch_one.my_function('not a real file path')
# note the two items, corresponding to the list in __enter__()
self.assertListEqual(['something from line', 'something from line'], ret_val)
# check the arguments, just for fun
self.assertEqual('rt', open_args[1])
Если вы хотите попробовать что-нибудь более сложное, Я бы порекомендовал прочитать макет юнит-тестовых документов, потому что то, как вы импортируете файл «patch_one», имеет значение, так же как и строка, которую вы передаете patch ().
Определенно найдется способ сделать это с помощью Mock или MagicMock, но я найти их немного сложными для отладки, поэтому я прошел долгий путь.