2

I have a Class based view defined as:

class Myview(LoginRequiredMixin, View):

    def post():
      #.......

to test this view i tried this

class MyViewTest(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.user = User.objects.create_user(
            username='jacob', email='soos@i.com', password='vvggtt')

    def view_test(self):
        # Create an instance of a POST request.
        request = self.factory.post('/my-url/')
        request.user = self.user

        response = MyView(request)
        print (response,"**")
        self.assertEqual(response.status_code, 200)

But this gives this error.

    response = MyView(request)
TypeError: __init__() takes 1 positional argument but 2 were given

I understand why this error is coming (cinstructor of MyView has 2 ars) but how do i remove it? i couldnt get the details on searching.

AshishRay94
  • 73
  • 1
  • 9
  • Have you implemented your own `__init__` method in `MyView`? If so could you post it? – user234461 May 18 '18 at 13:09
  • Normally `request` wouldn't be passed to the class constructor; see `https://docs.djangoproject.com/en/2.0/ref/class-based-views/base/#django.views.generic.base.View.as_view` – user234461 May 18 '18 at 13:09
  • @user234461 no i didnt implement __init__ in myview – AshishRay94 May 18 '18 at 13:11
  • @user234461 all i want is log in with a user and hit a post request and check if the response is correct – AshishRay94 May 18 '18 at 13:12
  • 1
    yeah well `MyView(request)` is wrong. The constructor doesn't take a request. See https://github.com/django/django/blob/master/django/views/generic/base.py – user234461 May 18 '18 at 13:18
  • Which method of `View` expects a `request`? The answer is right there in the function arguments - use the source, Luke. – user234461 May 18 '18 at 13:18
  • Possible duplicate of [How to unit test methods inside django's class based views?](https://stackoverflow.com/questions/33645780/how-to-unit-test-methods-inside-djangos-class-based-views) – Dušan Maďar May 18 '18 at 13:19
  • @user234461 i figured that after following the link you gave. but now i am gettinga another error `list_ = super().__getitem__(key) KeyError: 'nth_term'` . i am creating the post request as `request = self.factory.post('/my-url/', data={'nth_term': 5}, content_type='application/json')` – AshishRay94 May 18 '18 at 13:22
  • 1
    this worked when i removed the `content_type` – AshishRay94 May 18 '18 at 13:32

4 Answers4

3

we can use django test client

from django.test import Client

class MyViewTest(TestCase):
    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            username='jacob', email='soos@i.com', password='vvggtt')

    def view_test(self):
        # Create an instance of a POST request.
        self.client.login(username="jacob", password="vvggtt")
        data = {'name': 'test name'}
        res = self.client.post('/my-url/', data)
        print(res)
        self.assertEqual(res.status_code, 200)
anjaneyulubatta505
  • 10,713
  • 1
  • 52
  • 62
3

From the docs:

# Use this syntax for class-based views.
response = MyView.as_view()(request)
arcanemachine
  • 571
  • 4
  • 9
0

Try

response = MyView(request=request)
Dasith
  • 363
  • 2
  • 13
0

There's a section of the Django docs called Testing Class Based Views which addresses this:

In order to test class-based views outside of the request/response cycle you must ensure that they are configured correctly, by calling setup() after instantiation.

So in your case this looks something like:

    def view_test(self):
        # Create an instance of a POST request.
        request = self.factory.post('/my-url/')
        request.user = self.user

        my_view = MyView()
        my_view.setup(request)
        response = my_view.post(request)

        self.assertEqual(response.status_code, 200)
Nexus
  • 749
  • 6
  • 12