ptr
ptr

Reputation: 3384

unittesting: patching an objects __base__

Following on from this question, I attempted to patch class A() with Mock() so that when B() was initialised, the Mock was used as a base e.g.:

class A(object): ...
class B(A): ...

def setUp(self):
    with patch('A', new_callable=Mock) as MockObject:
        self.b = B()
        self.b.__class__.__base__ = MockOjbect

Which doesn't work because base is read only. What's the correct way to go about doing this?

update:

>>> from mock import Mock
>>> class A(object):
...     pass
... 
>>> class B(A):
...     pass
... 
>>> b.__class__.__bases__ = (Mock, )
>>> b.__class__.__bases__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/envs/myenv/local/lib/python2.7/site-packages/mock.py", line 656, in __getattr__
    elif self._mock_methods is not None:
  File "/opt/envs/myenv/local/lib/python2.7/site-packages/mock.py", line 655, in __getattr__
    raise AttributeError(name)
AttributeError: _mock_methods

To be clear, I'm not convinced this is the best way to achieve what I want to do, I'm half hoping someone else will come up with another way.

Upvotes: 2

Views: 1505

Answers (1)

James Mills
James Mills

Reputation: 19030

It's __bases__ which is a tuple.

Corrected version:

class A(object): ...
class B(A): ...

def setUp(self):
    with patch('A', new_callable=Mock) as MockObject:
        self.b = B()
        self.b.__class__.__bases__ = (MockOjbect,)

See:

>>> class Foo(object):
...     pass
... 
>>> Foo.__class__.__bases__
(<type 'object'>,)

tuple's are immutable but the __bases__ attribute is most certainly not read-only.

Upvotes: 2

Related Questions