I need to test the methods and helper function inside a django Class Based View.
Consider this Class Based View:
class MyClassBasedView(View):
def dispatch(self, request, *args, **kwargs):
....
def __get_render_dict():
d = {}
...
return d
def my_method(self):
render_dict = self.__get_render_dict()
return render_response(self.request, 'template.html', render_dict)
In order to write unit tests for my view, I need to call the methods inside, say __get_render_dict()
directly. How can I achieve this?.
I've tried
v = MyClassedBasedView()
v.dispatch(request,args, kwargs)
v.__method_name()
but this fails with not matching parameters in post/get method, even though I was calling the method direclty without using URL.
A typical unit test contains 3 phases: First, it initializes a small piece of an application it wants to test (also known as the system under test, or SUT), then it applies some stimulus to the system under test (usually by calling a method on it), and finally, it observes the resulting behavior.
There are cases where function-based views are better. In other cases class-based views are better. For example, if you are implementing a list view, and you can get it working just by subclassing the ListView and overriding the attributes. Great.
Every behavior should be covered by a unit test, but every method doesn't need its own unit test. Many developers don't test get and set methods, because a method that does nothing but get or set an attribute value is so simple that it is considered immune to failure.
To use class based views in your unittests try setup_view
from here.
def setup_view(view, request, *args, **kwargs):
"""
Mimic ``as_view()``, but returns view instance.
Use this function to get view instances on which you can run unit tests,
by testing specific methods.
"""
view.request = request
view.args = args
view.kwargs = kwargs
return view
You still need to feed it a request, you can do this with django.test.RequestFactory
:
factory = RequestFactory()
request = factory.get('/customer/details')
You can then unittest your methods:
v = setup_view(MyClassedBasedView(), request)
v.method_name()
As stated in Sebastian's answer he got the code snippet from django-downloadview docs. In there they state:
This is an early implementation of https://code.djangoproject.com/ticket/20456
A few years later, this feature is now part of Django, as you can read in the docs, so you would just need to do:
from django.test import RequestFactory, TestCase
from .views import MyClassBasedView
class MyClassBasedViewTest(TestCase):
def test_my_method(self):
request = RequestFactory().get('/')
view = MyClassBasedView()
view.setup(request)
view.my_method()
The view.setup()
method is precisely what was suggested in the accepted answer, but I think it is better to use the one from Django :)
I solved this issue by doing MyClassedBasedView.as_view()(request)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With