【问题标题】:mock __init__(self, ...): TypeError: super(type, obj): obj must be an instance or subtype of typemock __init__(self, ...): TypeError: super(type, obj): obj must be an instance or subtype of type
【发布时间】:2014-07-01 14:18:02
【问题描述】:

我尝试模拟这样的类的构造函数https://stackoverflow.com/a/17950141/633961

class MockedHttpResponse(django.http.response.HttpResponseBase):
    def check(self, *args, **kwargs):
        status=kwargs.get('status')
        if status is None and self.status_code==200:
            return # default 
        if not status==self.status_code:
            raise self.AssertionErrorStatusCode('%s!=%s' % (self.status_code, status))

    def __init__(self, *args, **kwargs):
        self.check(*args, **kwargs)
        django.http.response.HttpResponseBase.__init__(self, *args, **kwargs)

    class AssertionErrorStatusCode(AssertionError):
        pass

在测试中的使用:

def test_assert_http_response_status__with_self_mocking(self):
    from django.http import HttpResponse
    with mock.patch('django.http.response.HttpResponse', testutils.MockedHttpResponse):
        HttpResponse(status=200)

但我得到了这个例外:

Traceback (most recent call last):
  File "/home/foo_eins_di514/src/djangotools/djangotools/tests/unit/utils/test_testutils.py", line 129, in test_assert_http_response_status__with_self_mocking
    HttpResponse(status=200)
  File "/home/foo_eins_di514/lib/python2.7/site-packages/django/http/response.py", line 258, in __init__
    super(HttpResponse, self).__init__(*args, **kwargs)
TypeError: super(type, obj): obj must be an instance or subtype of type

如何模拟一个类并修改其__init__() 方法?

【问题讨论】:

  • 你使用的是哪个版本的 Django?
  • @SilasRay 我们使用 Django 1.5.8

标签: python django unit-testing mocking


【解决方案1】:

我不能肯定地说,因为我不是 mock 工作原理的专家,但除非它正在做一些非常令人印象深刻的体操,否则你已经将原始 django.http.HttpResponse 对象静态绑定到 HttpResponse 内测试模块范围 (from django.http import HttpResponse)。除非mock 在上下文管理器中动态修改locals() \ globals() 以修补对修补目标的别名引用,否则对模块本身的任何修补都不会影响您在测试中使用的HttpResponse 对象。我认为您至少需要采取的一个步骤是在patch 上下文管理器中显式地引用模块中的类,尽管看起来您也可以使用with mock.patch('django.http.response.HttpResponse', testutils.MockedHttpResponse) as HttpResponse: 来获得所需的结果。我认为您可能还想使用new_callable=testutils.MockedHttpResponse 作为patch 的kwarg。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-14
    • 2019-01-05
    • 2014-08-29
    • 2021-05-12
    • 2021-11-23
    • 2017-08-14
    • 2018-03-31
    • 1970-01-01
    相关资源
    最近更新 更多