简体   繁体   中英

Feature-testing a REST API with unittest in Django

In our Django project, we have some API views that are defined in urls.py like this:

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

and our calendar_api is an instance of CalendarAPI , which is instantiated above:

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

In the CalendarAPI class we have a method that fetches data from a remote CalDAV calendar using the caldav library like so:

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

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

We wish to mock this method in a way such that _get_event_list returns a predefined array.

Our test case looks like this:

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)

No matter what we try, we can't get mocking to work. If anyone knows of a better way to instantiate classes in urls.py in light of mocking, please let us know!

This always gets me as well. To mock a method on an instance of CalendarAPI , you need to mock the method on the return_value of the mock ( calendarapi_mock.return_value ).

With calendarapi_mock._get_event_list.return_value , you're mocking the method on the CalendarAPI class instead, ie CalendarAPI._get_event_list() .

So instead of

calendarapi_mock._get_event_list.return_value = mocked_calendar_events

use:

calendarapi_mock.return_value._get_event_list.return_value = mocked_calendar_events

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM