DSM верен, что по какой-то причине максимизированный экземпляр gzip.GzipFile
не заканчивается методом __exit__
. Вы получите точно такую же ошибку, если забудете определить __exit__
для класса, который вы используете с помощью оператора with
. Например:
>>> class C(object):
... def __enter__(self):
... return self
...
>>> with C() as c:
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: __exit__
К счастью, вы можете обойти эту проблему, используя метод CreateMockAnything()
Mox для создания mock_gzip_file
объекта, который не обеспечивает конкретного интерфейса. Вы должны быть осторожны, чтобы убедиться, что вы правильно настроили ожидания для объекта mock_gzip_file
(то есть, чтобы вы установили ожидания относительно того, когда и как будут вызываться методы __enter__()
и __exit__(...)
). Вот пример, который работал для меня:
import gzip
import mox
import unittest
class MyCode:
def generate_gzip_file(self):
with gzip.GzipFile('file_name.txt.gz', 'wb') as f:
f.write('data')
class MyCodeTest(unittest.TestCase):
def test_generate_gzip_file(self):
mymox = mox.Mox()
mock_gzip_file = mymox.CreateMockAnything()
mymox.StubOutWithMock(gzip, 'GzipFile')
gzip.GzipFile('file_name.txt.gz', 'wb').AndReturn(mock_gzip_file)
mock_gzip_file.__enter__().AndReturn(mock_gzip_file)
mock_gzip_file.write('data')
mock_gzip_file.__exit__(None, None, None).AndReturn(None)
mymox.ReplayAll()
MyCode().generate_gzip_file()
mymox.VerifyAll()
if __name__ == '__main__':
unittest.main()
Когда я запускаю это, я получаю:
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK