DJANGO REST和mongoengine的PUT测试案例

时间:2015-07-29 05:58:40

标签: python django mongodb unit-testing django-rest-framework

我正在使用DJango 1.8.3和mongo作为数据库,使用mongoengine开发基于休息的API。

我的models.py文件是

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)

正在按预期工作。 GET和POST测试用例工作正常

当我为PUT编写测试用例时,删除

我收到错误

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很明显它期待ID我尝试在url中传递客户端ID也作为请求中的seprate参数。

但是错误仍然相同,在这种情况下不知道如何传递id,感谢任何帮助。

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

docs似乎表明默认lookup_fieldpk而非id。我会尝试将网址格式更改为

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

或在视图中添加lookup_field属性

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

答案 1 :(得分:1)

终于想出来了

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)

调用视图(请求)时必须发送ID作为response = view(request,id = str(g_id))。

答案 2 :(得分:0)

更改您的代码并重新发布

urls.py

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

test.py    在url中,您传递的是pk值。在测试用例中,您还需要传递id的pk值。在上面的代码中,我吸收了你将id作为query-parameter传递,所以我将它作为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()