class Mock(_TestDouble): """Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive. """ __expectation__ =[]#[MockedCall(attribute, args, kargs),] __recording__ = RECORDING __traceroute__ = None __traceroute_expected__ = None __dependency_injection__ = None def __enter__(self): self.__traceroute__ = TraceRoute() self.__traceroute_expected__ = TraceRoute() self.__expectation__ = [] self.__recording__ = RECORDING self.__dependency_injection__ = DependencyInjection(double = self) return self def __methodCalled__(self, *args, **kargs): property = getframeinfo(getframe(1))[2] return self._property_called(property, args, kargs) def _property_called(self, property, args=[], kargs={}): if self.__recording__: self.__traceroute_expected__.remember() self._new_expectation(MockedCall(property, args = args, kargs = kargs, response = self)) return self else: self.__traceroute__.remember() return self._expectancy_recorded(property, args, kargs) def __exit__(self, type, value, traceback): self.__dependency_injection__.restoure_import() self.__recording__ = STOPRECORD def __setattr__(self, attr, value): if attr in dir(Mock): object.__setattr__(self, attr, value) else: self._property_called('__setattr__', args=[attr, value]) def _new_expectation(self, attr): self.__expectation__.append(attr) def __rshift__(self, response): self.__expectation__[-1].set_response(response) __lshift__ = __rshift__ def _expectancy_recorded(self, attr, args=[], kargs={}): try: if self._is_ordered(): return self._call_mocked_ordered(attr, args, kargs) else: return self._call_mocked_unordered(attr, args, kargs) except (CallExpectation, IndexError): raise MockExpectationError(self._unexpected_call_msg(attr, args, kargs)) def _unexpected_call_msg(self, attr, args, kargs): return ("Mock Object received unexpected call:%s\n" "Expected:\n" "%s\n" "Got:\n" "%s") % ( format_called(attr, args, kargs), self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_trace()) def _is_ordered(self): return self.__kargs__.get('ordered', True) def _call_mocked_unordered(self, attr, args, kargs): for number, call in enumerate(self.__expectation__): if call.has_callable(attr, args, kargs): call_mocked = self.__expectation__.pop(number) return call_mocked.call(attr, args, kargs) raise CallExpectation("Mock object has no called %s" %attr) def _call_mocked_ordered(self, attr, args, kargs): call_mocked = self.__expectation__.pop(0) return call_mocked.call(attr, args, kargs) def __getattr__(self, x): return self._property_called('__getattribute__',[x]) def validate(self): self.__dependency_injection__.restoure_object() if self.__expectation__: raise MockExpectationError( self._call_waiting_msg()) def __del__(self): self.__dependency_injection__.restoure_object() if self.__expectation__: print self._call_waiting_msg() def _call_waiting_msg(self): return("Call waiting:\n" "Expected:\n" "%s\n" "Got only:\n" "%s") % ( self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_code())
class Mock(_TestDouble): """Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive. """ __expectation__ = [] #[MockedCall(attribute, args, kargs),] __recording__ = RECORDING __traceroute__ = None __traceroute_expected__ = None __dependency_injection__ = None def __enter__(self): self.__traceroute__ = TraceRoute() self.__traceroute_expected__ = TraceRoute() self.__expectation__ = [] self.__recording__ = RECORDING self.__dependency_injection__ = DependencyInjection(double=self) return self def __methodCalled__(self, *args, **kargs): property = getframeinfo(getframe(1))[2] return self._property_called(property, args, kargs) def _property_called(self, property, args=[], kargs={}): if self.__recording__: self.__traceroute_expected__.remember() self._new_expectation( MockedCall(property, args=args, kargs=kargs, response=self)) return self else: self.__traceroute__.remember() return self._expectancy_recorded(property, args, kargs) def __exit__(self, type, value, traceback): self.__dependency_injection__.restore_import() self.__recording__ = STOPRECORD def __setattr__(self, attr, value): if attr in dir(Mock): object.__setattr__(self, attr, value) else: self._property_called('__setattr__', args=[attr, value]) def _new_expectation(self, attr): self.__expectation__.append(attr) def __rshift__(self, response): self.__expectation__[-1].set_response(response) __lshift__ = __rshift__ def _expectancy_recorded(self, attr, args=[], kargs={}): try: if self._is_ordered(): return self._call_mocked_ordered(attr, args, kargs) else: return self._call_mocked_unordered(attr, args, kargs) except (CallExpectation, IndexError): raise MockExpectationError( self._unexpected_call_msg(attr, args, kargs)) def _unexpected_call_msg(self, attr, args, kargs): return ("Mock Object received unexpected call:%s\n" "Expected:\n" "%s\n" "Got:\n" "%s") % (format_called(attr, args, kargs), self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_trace()) def _is_ordered(self): return self.__kargs__.get('ordered', True) def _call_mocked_unordered(self, attr, args, kargs): for number, call in enumerate(self.__expectation__): if call.has_callable(attr, args, kargs): call_mocked = self.__expectation__.pop(number) return call_mocked.call(attr, args, kargs) raise CallExpectation("Mock object has no called %s" % attr) def _call_mocked_ordered(self, attr, args, kargs): call_mocked = self.__expectation__.pop(0) return call_mocked.call(attr, args, kargs) def __getattr__(self, x): return self._property_called('__getattribute__', [x]) def validate(self): self.__dependency_injection__.restore_object() if self.__expectation__: raise MockExpectationError(self._call_waiting_msg()) def __del__(self): self.__dependency_injection__.restore_object() if self.__expectation__: print self._call_waiting_msg() def _call_waiting_msg(self): return ("Call waiting:\n" "Expected:\n" "%s\n" "Got only:\n" "%s") % (self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_code())