Testhelpers — Makes it easier to write tests for your cradmin views¶
Test case mixins¶
-
class
MockRequestResponse
(response, request)¶ Bases:
object
Return type of
TestCaseMixin.mock_request()
,TestCaseMixin.mock_http200_getrequest_htmls()
andTestCaseMixin.mock_postrequest()
.-
response
¶ The HttpResponse object.
-
request
¶ The RequestFactory-generated HttpRequest object.
-
selector
¶ A
htmls.S
object created with the entire content of the response as input. Only available when usingTestCaseMixin.mock_http200_getrequest_htmls()
.
-
-
class
AbstractTestCaseMixin
¶ Bases:
object
Implements the common API for the test case mixins.
-
viewclass
= None¶ The view class - must be set in subclasses unless you override
get_viewclass()
.
-
get_viewclass
()¶ Get the view class. Defaults to
viewclass
-
make_view
()¶ Make view function.
Calls
get_viewclass().as_view()
by default.
-
get_requestfactory_class
()¶ Get the request factory class.
Must be implemented in subclasses.
-
create_default_user_for_mock_request
()¶ Create default user for mock request.
Defaults to returning
mommy.make(settings.AUTH_USER_MODEL)
, which should create a user no matter what user model you are using, unless you do something very complex for users.You can override this if you want to change the default properties of users for all tests in this testcase, but it is normally better to just use the
requestuser
kwarg formock_request()
(or any of the more specializedmock_*request(..)
methods)Must return a user object compatible with
django.http.HttpRequest.user
. This means that the method can also return an AnonymousUser, but if you need this you should useNoLoginTestCaseMixin
(which just overrides this method).
-
make_minimal_request
(method, requestkwargs=None, httpheaders=None)¶ Make a minimal request object.
Parameters: method (str) – The http method (get, post, ...). - :param requestkwargs:: Kwargs for the request. Defaults to
{'path': '/'}
, and the path is added unless it is included in the dict. The data you can include in this dict is the same as for the get, post, ... methods ondjango.test.Client
(depends on themethod
kwarg).
:type requestkwargs:: dict :param httpheaders:: Extra http headers needed.
:type httpheaders:: dict
Returns: The created request object.
-
prettyformat_response_content
(response)¶ Must be implemented in subclasses.
-
mock_request
(method, cradmin_role=None, cradmin_app=None, cradmin_instance=None, requestuser=None, messagesmock=None, sessionmock=None, requestattributes=None, httpheaders=None, requestkwargs=None, viewkwargs=None, expected_statuscode=None, htmls_selector=False, verbose=False)¶ Create a mocked request using
make_requestfactory()
andmock.MagicMock
.Parameters: method – The http method (get, post, ...). - :param httpheaders:: Forwarded to
make_minimal_request()
. - Extra HTTP headers to be added to request.META.
:type httpheaders:: httpheaders :param requestkwargs:: Forwarded to
make_minimal_request()
.:type requestkwargs:: dict :param cradmin_role: The request.cradmin_role to use. Defaults to mock.MagicMock(). :param cradmin_app: The request.cradmin_app to use. Defaults to mock.MagicMock(). :param cradmin_instance: The request.cradmin_instance to use. Defaults to mock.MagicMock(). :param requestuser: The request.requestuser to use. Defaults to mock.MagicMock(). :param sessionmock: The request.session to use. Defaults to mock.MagicMock(). :param messagesmock: The request._messages to use. Defaults to mock.MagicMock().
Parameters: - requestattributes (dict) – Extra attributes to the reques to object.
This is applied before
add_essential_cradmin_attributes_to_request()
, so any of the attributes that method sets can not be in this dics. - viewkwargs (dict) – Kwargs for the view.
- expected_statuscode (int) – Expected status code. If this is
None
, we do not validate the status code. Defaults toNone
. - htmls_selector (boolean) – If this is
True
, we create ahtmls.S()
object for the response content. Should normally not be used without also providingexpected_statuscode
because it can lead to unexpected behavior. Defaults toFalse
. - verbose (boolean) – More verbose exception messages. Useful for debugging,
but should be
False
when you are not debugging. Defaults toFalse
.
- :param httpheaders:: Forwarded to
-
-
class
TestCaseMixin
¶ Bases:
django_cradmin.cradmin_testhelpers.AbstractTestCaseMixin
A mixin class that makes it easier to write tests for cradmin views.
It mocks all the required attributes of the request object.
Examples
Minimalistic:
from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_get_render_form(self): mockresponse = self.mock_http200_getrequest_htmls() mockresponse.selector.prettyprint() def test_post(self): mockresponse = self.mock_postrequest(requestkwargs={ 'data': { 'name': 'Jane Doe', 'age': 24 } }) self.assertEqual(mockresponse.response.status_code, 302)
Adding optional HTTP headers if needed:
from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_post_with_optional_httpheaders(self): self.mock_postrequest( cradmin_instance=cradmin_instance, httpheaders={ 'HTTP_REFERER': 'http://www.http-referent.com' }, requestkwargs={ 'data': { 'name': 'Jane Doe', 'age': 24 } }) self.assertEqual(mockresponse.response.status_code, 302)
Customizing the request.body, if e.g you have created a view that works as an API that handles POST with data. This data will in most cases be JSON. If this is not done through a form, but javascript, the data will end up in request.body, and not request.POST. To have this functionality when testing, simply add the data you want to _body in requestattributes. request._body is the actual attribute, and request.body is a property:
from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_post_with_optional_httpheaders(self): self.mock_postrequest( cradmin_instance=cradmin_instance, requestattributes={ '_body': b'{'key': 'value'}' }) self.assertEqual(mockresponse.response.status_code, 302)
Views that take arguments:
from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_get_render_form(self): # The kwargs for mock_postrequest, mock_http200_getrequest_htmls # and mock_getrequest are the same, so only showing one for brevity. mockresponse = self.mock_http200_getrequest_htmls(viewkwargs={'pk': 10})
Views that use a querystring (GET):
from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_get_render_form(self): mockresponse = self.mock_http200_getrequest_htmls( requestkwargs={ 'data': { 'orderby': 'name' } } )
Using a real user object:
from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_post(self): requestuser = mommy.make(settings.AUTH_USER_MODEL) mockresponse = self.mock_http200_getrequest_htmls(requestuser=requestuser)
Mocking Django messages framework messages:
from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_post(self): messagesmock = mock.MagicMock() mockresponse = self.mock_postrequest( requestkwargs={ 'data': { 'name': 'Jane Doe', 'age': 24 }, messagesmock=messagesmock ) messagesmock.add.assert_called_once_with( messages.SUCCESS, 'The data was posted successfully!', '')
Get a bit of extra information useful while debugging failing tests - use
verbose=True
(only for debugging, do not keep/commit verbose=True):from django_cradmin import cradmin_testhelpers class TestMyView(TestCase, cradmin_testhelpers.TestCaseMixin): viewclass = MyView def test_get(self): mockresponse = self.mock_http200_getrequest_htmls( verbose=True )
-
get_requestfactory_class
()¶ Get the request factory class. Defaults to
django.test.RequestFactory
.
-
-
class
NoLoginTestCaseMixin
¶ Bases:
django_cradmin.cradmin_testhelpers.TestCaseMixin
Use this instead of
TestCaseMixin
if you do not require an authenticated user in your view.-
create_default_user_for_mock_request
()¶ Overridden to return a
django.contrib.auth.models.AnonymousUser
object instead of creating a user.
-
-
class
RestFrameworkApiTestCaseMixin
¶ Bases:
django_cradmin.cradmin_testhelpers.TestCaseMixin
Django-rest-framework API test case mixin.
Works just like
TestCaseMixin
, except that it has a different debug output, and no*_htmls
methods.Assumes that the viewclass is a subclass of
rest_framework.views.APIView
.You can also make it work with viewsets by overriding
make_view()
and usereturn ViewSetClass.as_view({...})
there.
Utilities¶
Css classes only for automatic tests¶
You should use the cradmin_test_css_class()
template tag to add css classes that are only used in tests.
If you extend django_cradmin.renderable.AbstractRenderableWithCss
, you
can add css classes only for tests by overriding
get_test_css_class_suffixes_list()
.