It's typical to mock out some functionality in your Django tests using the patch decorator:
class LoginViewTest(TestCase): def setUp(self): # set some stuff up @patch('django_twitter_auth.views.redirect') def test_view_redirects_to_auth_url(self, mock_redirect): # do some testsIn the above example, we're replacing the redirect function with a Mock (technically a MagicMock) object. So whenever the redirect function is called within the context of the test_view_redirects_to_auth_url test, it'll actually be calling the Mock object which we have complete control over. If you want to mock out an object for a bunch of tests, you could apply the patch decorator to each test. You could also apply the patch decorator to the class itself:
@patch('django_twitter_auth.views.redirect') class LoginViewTest(TestCase): def setUp(self): # set some stuff up def test_view_redirects_to_auth_url(self, mock_redirect): # do some tests def some_other_test(self, mock_redirect): # do some testsBut if each test, for example, requires the mock_redirect to be setup and configured to behave a specific way, you'll easily end up repeating a lot of code in each test.
Unfortunately you can't just pass in the mocked object to your setUp method like this:
@patch('django_twitter_auth.views.redirect') class LoginViewTest(TestCase): def setUp(self, mock_redirect): # set the mock redirect for all the tests ...But wait! There is an alternative solution that allows you to configure your Mock objects in your test class' setUp method:
class LoginViewTest(TestCase): def setUp(self): # provide the location of the object you want to mock patcher = patch('django_twitter_auth.views.Twython') # explicitly start the patch self.mock_Twython = patcher.start() # make sure the patch is removed self.addCleanup(patcher.stop) # mock out all functionality required for view self.mock_Twython.some_attribute = "foo" self.mock_Twython.some_method.return_value = "bar" def test_Twython_instance_initialized_with_app_tokens(self): # the test has access to the Mock object! # let's do some fake setup here that's unique to # this test function mock_Twython_instance = self.mock_Twython.return_value # do some tests ... # assert some stuff def some_other_Twython_test(self): # this test also has access to the Mock object # watch him do some unique setup, like overriding # the default setup maybe? self.mock_Twython.some_method.return_value = "uniquebar" # do some tests ... # assert some stuffTake away the decorator magic, and patch can be used like a normal function. It returns a patcher object. When you call the patcher object's start() method, it returns the mocked out object. The only caveat is that you need to explicitly make sure the patching is "undone". This is what the:
self.addCleanup(patcher.stop)line in the setUp method in the above example does.
You can mock out multiple objects in setUp, just assign your patcher objects to different variable names like patcher_1, patcher_2, ..., etc. and then call patcher_1.start(), patcher_2.start(), ..., etc. to return the object each patcher object is mocking out.
You can read more about the start() and stop() methods in the official Mock documentation here.
Happy testing!