> On Oct 2, 2015, at 7:33 AM, Mashiat Sarker Shakkhar 
> <[email protected]> wrote:
> 
> On Thu, Oct 1, 2015 at 5:46 PM, Ashwini Oruganti <[email protected] 
> <mailto:[email protected]>> wrote:
> 
> 
> On Thu, Oct 1, 2015 at 1:40 PM, Mashiat Sarker Shakkhar 
> <[email protected] <mailto:[email protected]>>wrote:
> Hi
> 
> I have a function that uses callLater extensively to schedule a number of 
> different tasks. I don't want to get into the rationale behind such a design, 
> but here is a contrived example which will help me explain my problem: 
> 
>     def b():
>         '''Do some work'''
> 
>     def c():
>         '''Do some more work'''
> 
>     def a(flag):
>         if flag:
>             return Reactor.callLater(300, b)
>         else:
>             return Reactor. callLater(100, c)
> 
> Now I want to test this function. Of course I can't wait for 5 minutes to 
> ensure that `b` or `c` will indeed be called. What I need is some sort of 
> mock clock which lets me fast forward time. Does any such thing exist in 
> Twisted / Trial? 
> 
> Yes there is! `MemoryReactorClock.advance` 
> https://twistedmatrix.com/documents/current/api/twisted.test.proto_helpers.MemoryReactorClock.html
>  
> <https://twistedmatrix.com/documents/current/api/twisted.test.proto_helpers.MemoryReactorClock.html>
>  does this for you.
> 
> 
> HI Ashwini
> 
>  Thanks a lot for your response. I did come across MemoryReactorClock before, 
> but I could not figure out how to use it to test my code. I am using trial as 
> the test runner, which allows me to pass the name of the reactor to be used 
> in command line. But MemoryReactorClock is not available, because it is not 
> in twisted.internet.

Indeed, the MemoryReactorClock reactor is not suitable for installation in a 
global reactor.

> The code that I am testing imports reactor from twisted.internet in the 
> global scope. Do I have to change that and pass a reactor explicitly (say, as 
> a function parameter) where it is needed?

Yes.

> Is there any other way to change the default reactor to MemoryReactorClock 
> just for running tests?

You can hack it using patch 
<http://twistedmatrix.com/documents/15.2.0/api/twisted.trial.unittest.SynchronousTestCase.html#patch
 
<http://twistedmatrix.com/documents/15.2.0/api/twisted.trial.unittest.SynchronousTestCase.html#patch>>,
 by replacing the "reactor" attribute on your module.  But this is much worse 
than passing a parameter, and should only be used if you _really_ can't change 
the signature of your code for some reason.

> Going with my previous example, do I have to rewrite the code like following 
> or is there a better way?

You should rewrite code like the following, it would be better :).  But hey, 
this is Python, nobody can stop you from doing anything you want :).

>     def b():
>         '''Do some work'''
> 
>     def c():
>         '''Do some more work'''
> 
>     def a(myreactor, flag):
>         if flag:
>             return myreactor.callLater(300, b)
>         else:
>             return myeactor. callLater(100, c)
> 
> I do see this in the documentation:
> > New application code should prefer to pass and accept the reactor as a 
> > parameter where it is needed, rather than relying on being able to import 
> > this module to get a reference. This simplifies unit testing ...
> 
> But I'd prefer not to change the signature of existing functions.

Passing parameters to functions that need them is not a bad thing.  You should 
generally prefer that.  It seems a lot of Python programmers are very resistant 
to passing arguments, and would instead prefer that everything be a global 
variable.  I am honestly somewhat confused as to why :-).  But it's a bad habit 
and you should try to shake it.

-glyph

_______________________________________________
Twisted-Python mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to