【问题标题】:Mock patch results in error -- TypeError: object() takes no parameters in python 3模拟补丁导致错误——TypeError: object() 在 python 3 中没有参数
【发布时间】: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

我的问题:

  1. 为什么会出现这个错误?
  2. 为什么只发生在 python 3.x 上? (我使用的是 3.6)
  3. 这也会导致其他测试(在不同的测试用例中)失败,而如果我不使用失败的测试对其进行测试,它们通常会通过。这是为什么呢?
  4. 真的与嘲笑有关吗?我认为这是因为当我在服务器上进行测试时,功能就在这里。

编辑:添加回溯

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


【解决方案1】:

应该有 3 个模拟参数,除了 self. 像这样:

@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_validate, mock_validator_new, mock_parse):
   ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多