mock.patch decorator: missing 1 required positional argument: 'self'

蓝咒 提交于 2021-01-07 04:03:53

问题


I am trying to patch a variable in module settings during a test method run:

from unittest import mock

class Test(...):

    @mock.patch('settings.TARGET_SCORES_PER_SECTION', True)
    def test_register_user(self):

I am getting this error:

ERROR: tests.test_user.transplant_class.<locals>.C (test_register_user)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 1179, in patched
    return func(*args, **keywargs)
TypeError: test_register_user() missing 1 required positional argument: 'self'

I tried different approaches, could not find a solution.

What am I doing wrong?

This version works just fine:

    def test_register_user(self):
        with mock.patch('settings.TARGET_SCORES_PER_SECTION', True):
            self._test_register_user()

    def _test_register_user(self):

And I was hoping the using as a decorator would work in the same way.


回答1:


If I understand what you are trying to do, this will give you an idea of how to do it.

I have made settings.py hold just an assignment of False to TARGET_SCORES_PER_SECTION. Having to mention __main__ in the patch is just a little annoyance, it won't accept a non-qualified name.

import unittest
from unittest import TestCase
from unittest.mock import patch
import settings


def register_user():
    return settings.TARGET_SCORES_PER_SECTION


class Test(TestCase):

    @patch('__main__.settings')
    def test_register_user(self, mock_settings):
        # setup your mock
        mock_settings.TARGET_SCORES_PER_SECTION = True
        # test your function
        self.assertTrue(register_user())

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

Edit:

As I think to understand better OP question, the code above can also be changed to this if you like:

import unittest
from unittest import TestCase
from unittest.mock import patch
import settings


def register_user():
    return settings.TARGET_SCORES_PER_SECTION


class Test(TestCase):

    @patch('settings.TARGET_SCORES_PER_SECTION', True)
    def test_register_user(self):
        self.assertTrue(register_user())

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

Where True is the new parameter. This object is used to patch the place you mention in the patch string. This might be more elegant but requires you to have a configurated object for mocking at hand.



来源:https://stackoverflow.com/questions/55726728/mock-patch-decorator-missing-1-required-positional-argument-self

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!