Reputation: 1011
Currently I am doing TDD on a reusable Django app. One test should make sure that my view only returns articles that have a publish-date that is in the past. I am quite new to testing in Django. So far I have learned how to use .json
files as fixtures for my test classes.
However for this test I do not want to insert publish dates that are 1000 years in the future. After all another species might discover our ancient internet, check out my source and wonder why my test fails :) What other approaches are there to solve this problem? Static .json
files seem to be a bit hard to maintain as well as the application grows... mocking the datetime.datetime.now()
method in my tests feels tedious as well.
There must be an easy way to produce the .json
fixture on the fly before the test runs and always have 2 days from now as the publish-date for some of my entries...
Upvotes: 2
Views: 1565
Reputation: 39446
Indeed it is far more flexible to create your test data with Python. There are several packages that support such things, for instance
These two use fairly different approaches. Have a look and pick the one you like more. You can also write data generation functions from scratch. If you partition your logic carefully, this is not overly cumbersome.
For tests involving time, the right approach is indeed mocking -- but don't do it yourself, use a nice library. See for instance
There is even a pytest plugin for it.
Upvotes: 0
Reputation: 2836
You can try using django dynamic fixture, it will fill date/time properties automatically for you.
Upvotes: 0
Reputation: 1011
Mocking datetime was my first thought as well but as LaundroMat pointet out in his blog post himself, this is rather hacky and bad.
I came up with another solution:
I just gave up on .json fixtures. I don't even know why Django encourages to use them. They look ugly and they are impossible to maintain.
Instead I added a module test_data.py to my fixtures folder. That module imports my models and defines some nice methods that create test-data for me. In my tests.py I dropped the fixtures = ['some_json_file'] line and added a setUp() method instead. This method executes my 'dynamic fixtures' from my test_data.py module.
This is so simple and obvious that I wonder if there is anything wrong with this approach. If no one comments on this solution, I will mark is as accepted in a couple of weeks or so...
Upvotes: 1
Reputation: 8934
You could try subclassing the datetime functions (see "Using Mock objects in Django for testing the current date").
Upvotes: 1