[TIP] unittest/mock question

Michael Foord michael at voidspace.org.uk
Mon Sep 16 03:28:18 PDT 2013


On 14 Sep 2013, at 00:26, Christine Jones <cjjones at pixar.com> wrote:

> Hello,
> I've just started using Python unittest and mock. I've gone through the three Michael Foord tutorials, and read the docs, however, I cannot figure my way around this issue.
> 
> I am using Python 2.6 and mock 1.0.1.
> 
> I have the following function and tests. In brief, I am not able to test both branches of my if/else statement unless I comment out one or the other tests. Specifically, if I run both tests below only the last one passes. However, if I comment out the last one, the first one runs and passes. 
> 
> I was under the impression that patch automatically unmonkey patches when the context or function is left but it seems like maybe this is not happening. Or I am missing some other key concept. Any help would be greatly appreciated. Thank you in advance!
> Christine
> 
> My function:
> ======================
> # admin page: today's signups
> @app.route('/signups', methods=['GET'])
> def signups():
>   today = date.today()
>   players = LottoPlayer.query.filter(cast(LottoPlayer.signupdate, Date) ==        today).distinct(LottoPlayer.employeelogin).all()
>   player_count = players.__len__()
>   if player_count > 1:
>       return render_template("signups_today.html", signups=players)
>   else:
>       return render_template("signups_today.html")
> 
> Test for if branch:
> ======================
> # READ - GET signups - 200 (assumes > 0 signups)       
>   def test_signups_get(self):
>       today = datetime.datetime.now()
>       from lunchlottoweb import models
>       with patch.object(models, "LottoPlayer"):
>          players = [NonCallableMock(employeelogin='cjjones', employeedept='systems', signupdate=today, lottowinner=False),
>                     NonCallableMock(employeelogin='dlovirin', employeedept='systems', signupdate=today, lottowinner=False)]
>          LottoPlayer.all = players
>          request = MagicMock(name='signups_multiple_exist')
>          r = self.app.get('/signups')
>          assert 'cjjones' in r.data
> 
> Test for else branch:
> ======================
>   # READ - GET signups when there are 0 signups
>   def test_signups_get_when_none(self):
>       now = datetime.datetime.now()
>       yesterday = now - datetime.timedelta(days = 1)
>       from lunchlottoweb import models
>       with patch.object(models, 'LottoPlayer'):
>           players = [NonCallableMock(employeelogin='jshmo', employeedept='systems', signupdate=yesterday, lottowinner=False), 
>                     NonCallableMock(employeelogin='foo', employeedept='systems', signupdate=yesterday, lottowinner=False)]
>           LottoPlayer.all = players
> 


You're patching models.LottoPlayer - but directly modifying the LottoPlayer object (which is *not* your patched version).

Change LottoPlayer.all in your code above to models.LottoPlayer, *or* do the following, to fix your problem:

	with patch.object(models, 'LottoPlayer') as MockLottoPlayer:
		...
		MockLottoPlayer.all = players

Michael

>           request = MagicMock(name='signupsrequest')
>           r = self.app.get('/signups')
>           assert 'No one has signed up yet' in r.data
> 
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python


--
http://www.voidspace.org.uk/


May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing 
http://www.sqlite.org/different.html








More information about the testing-in-python mailing list