On 27 January 2015 at 13:00, Patryk Ĺciborek <patryk@sciborek.com> wrote:
Hi!
I've just started a new project using Twisted and I want to write unit tests since the beginning. Unfortunately I've got some trouble understanding how should I do it. I read 'Test-driven development with Twisted', read some articles on the web and searched on the mailing list but I couldn't find anything which make it clear for me.
I've got a class:
class SessionCleaner(object): def __init__(self, session_db, interval=10): self.session_db = session_db self.lc = task.LoopingCall(self.check_old_sessions)
def __init__(self, session_db, interval=10, reactor=reactor) self.lc = task.LoopingCall(self.check_old_sessions) self.lc.clock = reactor Then in tests you can replace the default reactor with twisted.internet.task.Clock In this way you have control over the looping call.
self.lc.start(interval)
@defer.inlineCallbacks def check_old_sessions(self): log.msg('check_old_sessions()', logLevel=logging.DEBUG) try: old_sessions = yield self.session_db.get_old_sessions() for s in old_sessions: yield self.session_db.process_stopped(s)
except txredisapi.ConnectionError as e: log.msg('check_old_sessions - connection error {}' .format(e), logLevel=logging.WARNING)
session_db is a object with methods which makes some calls to Redis.
In tests you can replace session_db with an InMemorySessionDB which is rigged to return on demand a failure or success. class InMemorySessionDB(object): def __init__(self): self._session = [] self._stop_session = {} def addRiggedSession(self, session, stop_result): self._session.append(session) self._stop_session[session] = stop_result def get_old_sessions(self) return self._session def process_stopped(self, session): return self._stop_session[session] InMemorySessionDB can also inherit form the real deal class and just overwrite exit points. This is more like a mock with a spec.. as it will fail if arbitrary methods are called with arbitrary arguments. I don't think there is a right way of doing it, but I try to avoid using generic Mock or MagicMock objects. Good luck! -- Adi Roiban