Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>EDIT</strong>: Since my answer is the accepted answer here I'm updating it to let everyone know a better way has been created in the meantime, the freezegun library: <a href="https://pypi.python.org/pypi/freezegun" rel="noreferrer">https://pypi.python.org/pypi/freezegun</a>. I use this in all my projects when I want to influence time in tests. Have a look at it.</p> <p><strong>Original answer:</strong></p> <p>Replacing internal stuff like this is always dangerous because it can have nasty side effects. So what you indeed want, is to have the monkey patching be as local as possible.</p> <p>We use Michael Foord's excellent mock library: <a href="http://www.voidspace.org.uk/python/mock/" rel="noreferrer">http://www.voidspace.org.uk/python/mock/</a> that has a <code>@patch</code> decorator which patches certain functionality, but the monkey patch only lives in the scope of the testing function, and everything is automatically restored after the function runs out of its scope.</p> <p>The only problem is that the internal <code>datetime</code> module is implemented in C, so by default you won't be able to monkey patch it. We fixed this by making our own simple implementation which <em>can</em> be mocked.</p> <p>The total solution is something like this (the example is a validator function used within a Django project to validate that a date is in the future). Mind you I took this from a project but took out the non-important stuff, so things may not actually work when copy-pasting this, but you get the idea, I hope :)</p> <p>First we define our own very simple implementation of <code>datetime.date.today</code> in a file called <code>utils/date.py</code>:</p> <pre><code>import datetime def today(): return datetime.date.today() </code></pre> <p>Then we create the unittest for this validator in <code>tests.py</code>:</p> <pre><code>import datetime import mock from unittest2 import TestCase from django.core.exceptions import ValidationError from .. import validators class ValidationTests(TestCase): @mock.patch('utils.date.today') def test_validate_future_date(self, today_mock): # Pin python's today to returning the same date # always so we can actually keep on unit testing in the future :) today_mock.return_value = datetime.date(2010, 1, 1) # A future date should work validators.validate_future_date(datetime.date(2010, 1, 2)) # The mocked today's date should fail with self.assertRaises(ValidationError) as e: validators.validate_future_date(datetime.date(2010, 1, 1)) self.assertEquals([u'Date should be in the future.'], e.exception.messages) # Date in the past should also fail with self.assertRaises(ValidationError) as e: validators.validate_future_date(datetime.date(2009, 12, 31)) self.assertEquals([u'Date should be in the future.'], e.exception.messages) </code></pre> <p>The final implementation looks like this:</p> <pre><code>from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import ValidationError from utils import date def validate_future_date(value): if value &lt;= date.today(): raise ValidationError(_('Date should be in the future.')) </code></pre> <p>Hope this helps</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload