Bypass decorator with mock in django test
I am trying to write a simple test however my views are decorated with nested user_passes_test statements. They check things like a stripe subscription and is_authenticated. I have found various posts such as this which address how to bypass a decorator with patch but I can't quite work out how to integrate everything together.
@patch('dashboard.views.authorised_base_user_checks', lambda func: func) def test_dashboard_root_exists(self): response = self.client.get('/dashboard/') self.assertEqual(200, response.status_code)
decorator in views
def authorised_base_user_checks(view_func): decorated_view_func = login_required(user_active(subscriber_exists(subscriber_valid(view_func)))) return decorated_view_func
@authorised_base_user_checks def IndexView(request): ...
The above still fails to pass through the decorator.
This approach with patching of decorator most probably does not work because import of
viewsmodule happens after the patching. If
viewhas been already imported the decorator had been already applied to
IndexViewand patching the decorator function would have no effect at all.
You can reload the view module to overcome this:
import imp import dashboard.views @patch('dashboard.views.authorised_base_user_checks', lambda func: func) def test_dashboard_root_exists(self): # reload module to make sure view is decorated with patched decorator imp.reload(views) response = self.client.get('/dashboard/') self.assertEqual(200, response.status_code) # reload again patch.stopall() imp.reload(views)
Disclaimer: this code only demonstrates the idea. You need to make sure
stopalland final reload always happens, so they should be in