如何在Python3中模拟带构造函数的对象?

1 投票
1 回答
1921 浏览
提问于 2025-04-16 23:35

我刚开始学习Python(之前是用Java),现在在使用Python3.2的mock时遇到了一些问题。

这是我的代码:

import gzip    

class MyClass:

    _content = None

    _gzipfile = gzip.GzipFile

    def __init__(self, content):
        self._content = content

    def my_method(self):
        # Code ...
        gzipper = self._gzipfile(fileobj=data)
        return gzipper.read()


import unittest
from mockito import *

class MyClassTest(unittest.TestCase):

    def my_method_test(self):
        gzipfile = mock
        myclass = MyClass()
        myclass._gzipfile = mock
        myclass.my_method

我想对我的方法进行单元测试(我在使用mockito库来做mock)。但是当我执行测试时,我收到了这个错误:

TypeError: __init__() got an unexpected keyword argument 'fileobj'

在这种情况下,我被迫用一个命名参数来调用GzipFile对象。

有没有什么好的方法可以mock这个GzipFile对象(还有类似的对象)呢?

1 个回答

0

你看到的这个 TypeError 错误,是因为你把 myclass._gzipfile 赋值给了 mockito.mock 这个类对象。所以当 my_method 用关键字参数 fileobj=data 调用 _gzipfile 时,实际上是在调用 mockito.mock 这个类,这就触发了它的 __init__ 方法,而这个方法并不理解这个参数。

像下面这样的代码应该能正常工作。虽然这仍然不是一个理想的单元测试,因为它依赖于 gzip.GzipFile,但这应该能帮助你入门。

import gzip

class MyClass(object):
    def __init__(self, content, file):
        self._content = content
        self._gzipper = gzip.GzipFile(filename=file)
    def my_method(self):
        # Code ...
        return self._gzipper.read()

import unittest
from mockito import *

class TestMyClass(unittest.TestCase):
    def setUp(self):
        self.my_class = MyClass('some content', 'file')

    def test_my_method(self):
    self.my_class._gzipper = mock()
        when(self.my_class._gzipper).read().thenReturn('gzipper read return')
        data = self.my_class.my_method()
        self.assertEqual(data, 'gzipper read return')

if __name__ == '__main__':
    unittest.main()

撰写回答