Reputation: 2304
Is there a way to just set a parent object to a particular instance? I have a utility that initializes a complex object for me and i'd like to have it init some objects for mocking. Example:
class ComplexObject:
def __init__(arg1, arg2, arg3):
#do some stuff
return
class ComplexObject_Mock(ComplexObject):
def __init__():
complexObject = ComplexObjectFactory.NewComplexObject()
return super() = complexObject
Now I know the above doesn't work, because of the last line. Usually I create the instance of the parent class by using super().__init(arg1, arg2, arg3)
, but instead of that i'd like to just set the instance to something initialized by the factory.
Upvotes: 1
Views: 1349
Reputation: 365707
First, there are multiple problems with this line:
return super() = complexObject
return
, only an expression.super()
returns a special magic proxy object, so forcing it to return some other object that doesn't know how to act like a super
would just break everything.super()
returns is a proxy to self
. If you somehow made it into a proxy into a completely unrelated object, then every method you called on super()
would end up accessing and mutating the attributes of that completely unrelated object, which would have no effect on self
.Also, __init__
is a normal method, that requires a self
or it can't be called.
Meanwhile, if you're trying to change the way an object is created, not just the way it's initialized, you have to use __new__
, not __init__
.
Finally, the whole point of mocking is that you don't have to create a ComplexObject
; you're creating something that acts like one without being one, so the whole thing doesn't make much sense in the first place.
This is kind of a wild guess, but I think what you really want here is a proxy object that owns a ComplexObject
, and also fakes being one, delegating some calls and handling others on its own. In other words:
class ComplexObject_Mock(ComplexObject):
def __init__(self):
self.complexObject = ComplexObjectFactory.NewComplexObject()
def method_to_delegate(self, arg):
# instead of return super().method_to_delegate(arg)
return self.complexObject.method_to_delegate(arg)
def method_to_steal(self, arg):
# don't call self.complexObject.method_to_steal
# just as you wouldn't have called super().method_to_steal
def method_to_hook(self, arg):
arg = self._preprocess(arg)
# instead of result = super().method_to_hook(arg)
result = self.complexObject.method_to_hook(arg)
return self._postprocess(result)
Upvotes: 1