【问题标题】:Test Cases For PUT in DJANGO REST and mongoengineDJANGO REST 和 mongoengine 中的 PUT 测试用例
【发布时间】:2015-10-19 22:48:59
【问题描述】:

我使用 DJango 1.8.3 和 mongo 作为数据库,使用 mongoengine 开发基于 rest 的 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") 

序列化器.py 类 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 编写测试用例时,DELETE

我收到了错误

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

从错误很明显,我尝试在 url 中传递客户端 ID 作为请求中的单独参数。

但错误仍然相同,在这种情况下不知道如何传递 id 任何帮助表示赞赏。

提前感谢您的帮助

【问题讨论】:

  • 建议不要在同一个测试中测试post 和delete,因为您只是在这里尝试测试delete。

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


【解决方案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)

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

【讨论】:

    【解决方案2】:

    docs 似乎表明默认的lookup_field 是pk 而不是id。我会尝试将 url 模式更改为

    ...
    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
    

    【讨论】:

      【解决方案3】:

      更改代码并重新发布

      urls.py

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

      test.py 在您传递 pk 值的 url 中。在测试用例中,您还需要传递 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()
      

      【讨论】:

      • 我已经试过了,我已经把它作为我的代码中的注释。这也给出了同样的问题
      猜你喜欢
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多