【发布时间】:2020-01-17 18:19:09
【问题描述】:
这有点复杂,因为我正在调试一些很久以前用 python 2.7 编写的代码
正在迁移到 Python 3(我知道,我知道)并在尝试修复单元测试时遇到此问题
问题是我收到错误TypeError: object() takes no parameters
我将在下面列出函数。我必须替换很多函数和对象的名称。如果您发现模块名称不一致,则认为是拼写错误。
首先是它调用的类
class Parser(object):
def __init__(self, some_instance, some_file):
self._some_instance = some_instance
self.stream = Parser.formsomestream(some_file)
self.errors = []
@staticmethod
def formsomestream(some_file):
# return a stream
class BetterParser(Parser):
def parse(self):
# skip some steps, shouldn't relate to the problem
return details # this is a string
class CSVUploadManager(object):
def __init__(self, model_instance, upload_file):
self._model_instance = model_instance
self._upload_file = upload_file
# then bunch of functions here
# then.....
def _parse(self):
parser_instance = self._parser_class(self._model_instance, self._upload_file)
self._csv_details = parser_instance.parse()
# bunch of stuff follows
def _validate(self):
if not self._parsed:
self._parse()
validator_instance = self._validator_class(self._model_instance, self._csv_details)
# some attributes to set up here
def is_valid(self):
if not self._validated:
self._validate()
现在是测试功能 从某处.to.this.validator 导入 MockUploadValidator 从另一个地方导入 CSVUploadManager
class TestSomething(SomeConfigsToBeMixedIn):
@mock.patch('path.to.BetterParser.parse')
@mock.patch('path.to.SomeValidator.__new__')
@mock.patch('path.to.SomeValidator.validate')
def test_validator_is_called(self, mock_validator_new, mock_parse):
mock_validator_new.return_value = MockUploadValidator.__new__(MockUploadValidator)
mock_parse.return_value = mock_csv_details
mock_validator_new.return_value = MockUploadValidator()
string_io = build_some_string_io_woohoo() # this returns a StringIO
some_file = get_temp_from_stream(string_io)
upload_manager = CSVUploadManager(a_model_instance, some_file)
upload_manager.is_valid() # this is where it fails and produces that error
self.assertTrue(mock_parse.called)
self.assertTrue(mock_validator_new.called)
validator_new_call_args = (SomeValidator, self.cash_activity, mock_csv_details)
self.assertEqual(mock_validator_new._mock_call_args_list[0][0], validator_new_call_args)
如你所见,CSVUploadManager 接收一个 django 模型实例和一个类似文件的 obj,这个东西会触发 self._parser_class,它调用 BetterParser,然后 BetterParser 做它的事情。
但是,我猜这是由于模拟,它返回 TypeError: object() takes no parameters
我的问题:
- 为什么会出现这个错误?
- 为什么只发生在 python 3.x 上? (我使用的是 3.6)
- 这也会导致其他测试(在不同的测试用例中)失败,而如果我不使用失败的测试对其进行测试,它们通常会通过。这是为什么呢?
- 真的与嘲笑有关吗?我认为这是因为当我在服务器上进行测试时,功能就在这里。
编辑:添加回溯
Traceback (most recent call last):
File "/path/to/lib/python3.6/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File "/path/to/test_file.py", line 39, in test_validator_is_called:
upload_manager.is_valid()
File "/path/to/manager.py", line 55, in is_valid
self._validate()
File "/path/to/manager.py", line 36, in _validate
validator_instance = self._validator_class(self._model_instance, self._csv_details)
TypeError: object() takes no parameters
【问题讨论】:
-
你需要分享回溯
-
@IainShelvington 添加了回溯
标签: django python-3.x mocking django-unittest