6π
I donβt use Django and maybe there is some idiomatic way to do it well in Django.
My approach to this kind of problem is to create my own TestCase
class that extend from unittest.TestCase
and override setUpClass()
/tearDownClass
/setUp()
/tearDown()
to set up the mock/patch that I need globally in my tests (or at least in a part of them).
Now every time I need it instead of importing unittest.TestCase
module Iβm importing myunittest.TestCase
Example: myunittest.py
import unittest
class TestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
super(TestCase, cls).setUpClass()
# Init your class Mock/Patch
@classmethod
def tearDownClass(cls):
# Remove Mocks or clean your singletons
super(TestCase, cls).tearDownClass()
def setUp(self):
super(TestCase, self).setUp()
# Init your obj Mock/Patch
@classmethod
def tearDown(self):
# ... if you need it
super(TestCase, self).tearDown()
And in your tests:
from myunittest import TestCase
class Test(TestCase):
... Your test
7π
Two ways that I have used in a big django project
Assuming a: my_mock = patch("myapp.mymodule.MyClass.my_method")
1) You can add a mock inside a custom test runner class:
from mock import patch
from django.test.runner import DiscoverRunner
class MyTestRunner(DiscoverRunner):
@my_mock
def run_tests(self, test_labels, **kwargs):
return super(MyTestRunner, self).run_tests(test_labels, **kwargs)
2) You can add a mock on a custom base test class:
from mock import patch
from django.test import TestCase
class MyTestCase(TestCase):
def setUp(self):
super(MyTestCase, self).setUp()
my_mock.start()
def tearDown(self):
super(MyTestCase, self).tearDown()
my_mock.stop()
- How to append pages of data using jQuery and Django pagination?
- How to make a field editable on create and read-only on update in Django REST framework
0π
Below are two methods to implement mocking.
Method 1: With modifications to production code:
You can create a pseudo-package and import it for testing instead of importing the original package. This check-based-import could be done at the beginning of every file.
For example:
import os
if 'TEST' in os.environ:
import pseudoTime as time
else:
import time
print time.time
Method 2: No modifications to production code:
In your test program, you could import the utility package ( the package containing the email function described in the question) and overwrite the utility function.
For example:
Consider the following code:
import time
def function():
return time.time()
The test code could do the following:
import code
import time
def helloWorld():
return "Hello World"
print "Before changing ...", code.function()
oldTime = time.time # save
time.time = helloWorld
print "After changing ...", code.function()
time.time = oldTime # revert back
The output for above test was:
Before changing ... 1456487043.76
After changing ... Hello World
Thus the test code can import the utility file, overwrite the function it provides and then run the tests on production code.
This method is superior as it does not change production code.
- Django tests complain of missing tables
- What is the difference between a Multi-table inherited model and a simple One-to-one relationship between the same two models?
- Facebook, Django, and Google App Engine
- Displaying multiple Rows and Columns in django-crispy-forms