【问题标题】:Python unit test how to use Mox to mock the gzip with statementPython 单元测试如何使用 Mox 模拟 gzip with 语句
【发布时间】:2012-01-18 05:09:15
【问题描述】:

在 Python 中,如何使用 mox 单元测试库模拟在 with 语句中创建的对象

代码

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):
        mox = mox.Mox()
        mock_gzip_file = self.mox.CreateMock(gzip.GzipFile)
        mox.StubOutWithMock(gzip, 'GzipFile')
        gzip.GzipFile('file_name.txt.gz','wb').AndReturn(mock_file)
        mock_gzip_file.write('data')
        mox.ReplayAll()
        MyCode().generate_gzip_file()
        mox.VerifyAll()

我在线收到错误AttributeError: __exit__

with gzip.GzipFile('file_name.txt.gz','wb') as f:

【问题讨论】:

  • 您使用的是 python 2.6 或更低版本吗?我认为 GzipFile 直到 2.7 才支持上下文管理。如果是这样,您可能必须编写自己的(小)包装器。
  • GzipFile 支持迭代和 with 语句。根据文档docs.python.org/library/gzip.html
  • 是的,正如我所说,这是 2.7 附带的,因为您运行的是 2.7,所以这不是问题。我认为发生的事情是存根版本没有以__exit__ 结束。我认为你必须确保 with 被模拟(参见garybernhardt.github.com/python-mock-comparison 的示例——搜索“上下文管理器”并查看 Mox 示例。)

标签: python unit-testing gzip mox


【解决方案1】:

DSM 是正确的,gzip.GzipFile 的模拟实例由于某种原因没有以 __exit__ 方法结束。如果您忘记在使用with 语句的类上定义__exit__,您将得到完全相同的错误。例如:

>>> 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__

幸运的是,您可以通过使用 Mox 的 CreateMockAnything() 方法创建一个不强制执行特定接口的 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    • 2017-07-03
    • 2021-02-16
    • 2011-02-26
    • 2011-01-31
    相关资源
    最近更新 更多