AttributeError:__name__ 在 djangorestframework 3.8.2 中运行测试

Posted

技术标签:

【中文标题】AttributeError:__name__ 在 djangorestframework 3.8.2 中运行测试【英文标题】:AttributeError: __name__ running test in djangorestframework 3.8.2 【发布时间】:2021-04-20 03:40:39 【问题描述】:

我目前在 DRF 3.7.7 上运行,但正在升级到 DRF 3.8.2,针对 python 3.8 运行。我有一个在升级之前通过的测试,但在升级之后,我在测试中遇到错误AttributeError: __name__

注意:我已经更改了一些变量名,所以如果我遗漏了任何东西,命名可能会有些不一致

class ProductViewSetTestCase():
    def setUp(self):
        super().setUp()

        self.product = self.create_product()

        self.client = Client(HTTP_HOST='.localtest.me:8000'.format(self.account.domain))
        self.client.login(username=self.user, password=self.user_password)

    def send_refund_request(self, amount=5000):
        url = reverse('product-refund', kwargs='pk': self.product.id)
        data = json.dumps('amount': amount, 'reason': 'dont want it!')

        return self.client.post(url, data=data, secure=True, content_type='application/json')

    @mock.patch('apps.product.api.ProductViewSet.get_object')
    def test_refund_request_will_succeed(self, mock_get_object):
        mock_get_object.return_value = self.product
        with mock.patch.object(self.product, 'process_refund') as process_refund:
            process_refund.return_value.transaction.product = self.product
            response = self.send_refund_request()
            assert response.status_code == HTTP_200_OK

以下是堆栈跟踪。似乎在 reverse 方法中抛出错误,但这与我在测试用例中所做的模拟有关。

    @mock.patch('apps.product.api.ProductViewSet.get_object')
    def test_refund_request_will_succeed(self, mock_get_object):
        mock_get_object.return_value = self.product
        with mock.patch.object(self.product, 'process_refund') as process_refund:
            process_refund.return_value.transaction.product = self.product
>           response = self.send_refund_request()

bentobox/apps/product/tests/test_product.py:148: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
bentobox/apps/product/tests/test_product.py:120: in send_refund_request
    url = reverse('product-refund', kwargs='pk': self.product.id)
../venv/lib/python3.8/site-packages/django/urls/base.py:90: in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
../venv/lib/python3.8/site-packages/django/urls/resolvers.py:569: in _reverse_with_prefix
    self._populate()
../venv/lib/python3.8/site-packages/django/urls/resolvers.py:418: in _populate
    for url_pattern in reversed(self.url_patterns):
../venv/lib/python3.8/site-packages/django/utils/functional.py:36: in __get__
    res = instance.__dict__[self.name] = self.func(instance)
../venv/lib/python3.8/site-packages/django/urls/resolvers.py:540: in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
../venv/lib/python3.8/site-packages/django/utils/functional.py:36: in __get__
    res = instance.__dict__[self.name] = self.func(instance)
../venv/lib/python3.8/site-packages/django/urls/resolvers.py:533: in urlconf_module
    return import_module(self.urlconf_name)
/usr/lib/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
<frozen importlib._bootstrap_external>:783: in exec_module
    ???
<frozen importlib._bootstrap>:219: in _call_with_frames_removed
    ???
bentobox/urls.py:89: in <module>
    urlpatterns += [url(r'^api/', include('apps.api.urls'))]
../venv/lib/python3.8/site-packages/django/urls/conf.py:34: in include
    urlconf_module = import_module(urlconf_module)
/usr/lib/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1014: in _gcd_import
    ???
<frozen importlib._bootstrap>:991: in _find_and_load
    ???
<frozen importlib._bootstrap>:975: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:671: in _load_unlocked
    ???
<frozen importlib._bootstrap_external>:783: in exec_module
    ???
<frozen importlib._bootstrap>:219: in _call_with_frames_removed
    ???
bentobox/apps/api/urls.py:366: in <module>
    urlpatterns = router.urls
../venv/lib/python3.8/site-packages/rest_framework/routers.py:101: in urls
    self._urls = self.get_urls()
../venv/lib/python3.8/site-packages/rest_framework/routers.py:363: in get_urls
    urls = super(DefaultRouter, self).get_urls()
../venv/lib/python3.8/site-packages/rest_framework/routers.py:261: in get_urls
    routes = self.get_routes(viewset)
../venv/lib/python3.8/site-packages/rest_framework/routers.py:179: in get_routes
    not_allowed = [
../venv/lib/python3.8/site-packages/rest_framework/routers.py:181: in <listcomp>
    if action.__name__ in known_actions
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MagicMock name='get_object' id='140667993171664'>, name = '__name__'

    def __getattr__(self, name):
        if name in '_mock_methods', '_mock_unsafe':
            raise AttributeError(name)
        elif self._mock_methods is not None:
            if name not in self._mock_methods or name in _all_magics:
                raise AttributeError("Mock object has no attribute %r" % name)
        elif _is_magic(name):
>           raise AttributeError(name)
E           AttributeError: __name__

我的 urls.py:

urlpatterns += [url(r'^api/', include('apps.api.urls'))]

api/url

router = DefaultRouter(trailing_slash=False)
... (a bunch of router.register)
router.register(r'product', ProductViewSet, base_name='product')
...

我尝试过添加mock_get_object.__name__='refund' 之类的方法,但它只会引发其他错误。我不确定 DRF 3.8.2 中的什么导致了这个问题。任何帮助或建议表示赞赏。

【问题讨论】:

你能分享你的 urls.py 文件吗? @ruddra 我分享了 urls.py 看起来像什么的 sn-ps 【参考方案1】:

我也有同样的问题。请尝试将autospec=True 设置为您的模拟。 所以它看起来像

with mock.patch.object(self.product, 'process_refund', autospec=True) as process_refund:
    ...

这帮助我解决了问题

【讨论】:

以上是关于AttributeError:__name__ 在 djangorestframework 3.8.2 中运行测试的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“顺序”对象在 Keras Theano 中没有属性“_feed_input_names”

django-celery 管理命令给出 AttributeError: '_multiprocessing.SemLock' 对象没有属性 'name'

Windows 上的 Python DEAP 和多处理:AttributeError

AttributeError: 'int' object has no attribute 'log'

AttributeError:模块“__main__”没有属性“AverageWordLengthExtractor”

pickle load文件时报AttributeError: Can't get attribute 'Cours' on <module '__main__&#