Ложное исправление приводит к ошибке - TypeError: object () не принимает параметров в python 3 - PullRequest
0 голосов
/ 17 января 2020

Это немного сложно, потому что я отлаживаю некоторый код, написанный долгое время за go в 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 из другого. place import 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

1 Ответ

0 голосов
/ 22 апреля 2020

Должно быть 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):
   ...
...