在Django中使用unittest对REST API进行功能测试

问题描述

在我们的Django项目中,我们在urls.py中定义了一些API视图,如下所示:

path('api/calendar/calendar_data',calendar_api.serve_data),

而我们的calendar_apiCalendaraPI的实例,该实例在上方进行了实例化:

from main.calendar_api import CalendaraPI
from caldav import DAVClient
...
calendar_api = CalendaraPI(client=DAVClient(...))

在CalendaraPI类中,我们有一个使用caldav库从远程CalDAV日历中获取数据的方法,如下所示:

class CalendaraPI(ApiEndpoint):
...
  def __init__(self,client):
    self.caldav_client = client

  def _get_event_list(self):
    return self.caldav_client.principal().calendars()[0].events()

我们希望以_get_event_list返回预定义数组的方式来模拟此方法

我们的测试用例如下:

from unittest.mock import patch
from django.test import SimpleTestCase

class TestCalendar(SimpleTestCase):
  @patch('main.urls.CalendaraPI')
  def test_response_format(self,calendarapi_mock):
    calendarapi_mock._get_event_list.return_value = mocked_calendar_events
    response = self.client.get('/api/calendar/calendar_data',format='json')
    # fails test if response does not match mocked_calendar_events
    self._compareResponse(response,mocked_calendar_events)

无论我们尝试什么,我们都无法进行模拟工作。如果有人知道根据嘲笑在urls.py中实例化类的更好方法,请告诉我们!

解决方法

这也总是使我受益。要在// lookup our user and external provider info var (user,provider,providerUserId,claims) = await FindUserFromExternalProvider(result); if (user == null) { // SignUp user } 实例上模拟方法,您需要在模拟(CalendarAPI)的return_value上模拟方法。

使用calendarapi_mock.return_value,您可以在calendarapi_mock._get_event_list.return_value类上模拟该方法,即CalendarAPI

因此,请执行以下操作,而不要使用CalendarAPI._get_event_list()

calendarapi_mock._get_event_list.return_value = mocked_calendar_events