Hi James,

Thank you for Your response, it was very helpful :) I hope you don't mind if I use your testing.py in my project. I wrote tests for the SessionCleaner class and they seems to be OK (https://github.com/scibi/pyradacctsrv/blob/master/tests/test_cleaner.py).

I saw your post from July 2013 but that thread was more about docstrings and checking return values of test methods than mocking and deferreds ;)

Kind regards,
Patryk

On Tue, Jan 27, 2015 at 3:48 PM, James Broadhead <jamesbroadhead@gmail.com> wrote:
Since then, our approach has evolved into the below, which may be useful.
https://github.com/jamesbroadhead/bttrtwisted/blob/master/bttrtwisted/testing.py

Usage:
  expected = Foo()
  remote_result = Result()
  thing = Thing()
  thing.call_external_service = dmockfunc(remote_result)

  d = thing.function_under_test(..)
  d.addCallback(self.assertEqual, expected)
  return d

You can use the func_dict param to gen_nondeferred_mock to have it stand in-place-of an object

As always with mocks, a little can be helpful, but if you find you're instantiating a lot of them, you may want to reconsider your approach.

Feedback welcome!
[ the repo is for experiments, so use with care ]

James

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)
        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.

Testing if __init__ works correctly is easy - I can mock task.LoopingCall and check if it was called with correct attributes.

I've got trouble testing check_old_sessions. Since I'm writing unit tests I don't want to call real session_db methods and make real Redis queries. I'd like to mock them and test just few things:
- is the method get_old_sessions called?
- is the method process_stopped called N times with the arguments returned by mocked get_old_sessions?
- is txredisapi.ConnectionError handled correctly?

So is there any "right" way of mocking functions which returns deferreds? Or maybe I should test this method differently?

Best regards,
Patryk

_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python



_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python