Alok Agarwal
Alok Agarwal

Reputation: 3099

Test Cases For PUT in DJANGO REST and mongoengine

I am using DJango 1.8.3 and mongo as database using mongoengine for developing rest based API.

My models.py file is

class Client(Document):
    client_name = StringField(max_length=50)
    client_email = EmailField()
    city = StringField(max_length=50)
    country = StringField(max_length=200, verbose_name="Country") 

Serializers.py class ClientSerializer(DocumentSerializer):

    class Meta:
        model = Client
        depth = 1

views.py

class ClientDetails(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()

class ClientList(generics.ListCreateAPIView):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()

urls.py

urlpatterns = [
url(r'^client/$', views.ClientList.as_view(), name='client'),
url(r'^client/(?P<id>[\w]{24})/$', views.ClientDetails.as_view(),
    name='client_details'),
]

test.py

def test_get_client(self):
    """
    Ensure we get existing clients from mongo database.
    """
    url = '/client_management/client/'
    factory = APIRequestFactory()
    user = User.objects.get(username='jacob')
    view = views.ClientList.as_view()

    # Make an authenticated request to the view...
    request = factory.get(url)
    force_authenticate(request, user=user)
    response = view(request)
    self.assertEqual(response.status_code, 200)

def test_delete_client(self):
    """
    Ensure we can delete new clients in mongo database.
    """
    url = '/client_management/client/'
    data = {'client_name'='XX'}
    factory = APIRequestFactory()
    user = User.objects.get(username='jacob')
    view = views.ClientList.as_view()

    # Make an authenticated request to the view...
    request = factory.post(url, data=data,)
    force_authenticate(request, user=user)
    response = view(request)
    ##self.assertEqual(response.status_code, status.HTTP_201_CREATED)

    g_id = response.data['id']
    urls = '/client_management/client/?id=' + g_id
    ## even tried
    ## urls = '/client_management/client/ + g_id + /
    data['id'] = g_id
    #data['client_name'] = 'MAA'
    view = views.ClientDetails.as_view()
    request = factory.delete(urls)
    ## tried this also
    ## request = factory.delete('/client_management/client/', id=g_id)
    print request
    force_authenticate(request, user=user)
    response = view(request)
    self.assertEqual(response.status_code, 201)

which is working as expected. GET AND POST test cases are working fine

When I am writing Test cases for PUT, DELETE

I am getting the error

Expected view ClientDetails to be called with a URL keyword argument named "id".
Fix your URL conf, or set the `.lookup_field` attribute on the view correctly

From Error It is clear it is expecting ID I tried passing client ID in url also as a seprate parameter in request.

But error is still same, don't know how to pass id in this case any help is appreciated.

Advance thanks for help

Upvotes: 1

Views: 635

Answers (3)

Alok Agarwal
Alok Agarwal

Reputation: 3099

Finally Figured it out

def test_delete_client(self):
    """
    Ensure we can delete new clients in mongo database.
    """
    url = '/client_management/client/'
    data = {'client_name'='XX'}
    factory = APIRequestFactory()
    user = User.objects.get(username='jacob')
    view = views.ClientList.as_view()

    # Make an authenticated request to the view...
    request = factory.post(url, data=data,)
    force_authenticate(request, user=user)
    response = view(request)
    ##self.assertEqual(response.status_code, status.HTTP_201_CREATED)

    g_id = response.data['id']
    urls = '/client_management/client/?id=' + g_id
    ## even tried
    ## urls = '/client_management/client/ + g_id + /
    data['id'] = g_id
    #data['client_name'] = 'MAA'
    view = views.ClientDetails.as_view()
    request = factory.delete(urls)
    ## tried this also
    ## request = factory.delete('/client_management/client/')
    print request
    force_authenticate(request, user=user)
    response = view(request, id=str(g_id))
    self.assertEqual(response.status_code, 201)

You have to send ID when calling view(request) as response = view(request, id=str(g_id)).

Upvotes: 1

pingul
pingul

Reputation: 3473

The docs seems to indicate that the default lookup_field is pk and not id. I would try to either change the url pattern to

...
url(r'^client/(?P<pk>[\w]{24})/$', views.ClientDetails.as_view(),
    name='client_details'),
...

or add a lookup_field attribute to your view

class ClientDetails(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()
    lookup_field = ('id',) # Note the parenthesis, they are needed so the object is a tuple

Upvotes: 1

Seenu S
Seenu S

Reputation: 3481

Change your code and reposting

urls.py

urlpatterns = [
    url(r'^client/(?P<id>[\w]{24})/$', views.ClientDetails.as_view(),
    name='client_details'),
]

test.py In the url you are passing the pk value. In the test case also you need to pass the pk value of id. In the above code i absorbed that you passing id as query-parameter so i'm passing it as pk.

def test_delete_client(self):
    """
    Ensure we can delete new clients in mongo database.
    """
    g_id = response.data['id']
    urls = '/client_management/client/' + str(g_id) + '/'
    view = views.ClientDetails.as_view()

Upvotes: 0

Related Questions