I have a problem that I don't know how to make it work.
urls.py:
urlpatterns = [
url(r'athletes/search$', SearchAthletes.as_view()),
url(r'athletes/([0-9]+)$', ViewAthlete.as_view())
]
views.py:
class ViewAthlete(APIView):
def get(self, request, id, format=None):
athlete = Athlete.objects.get(id=id)
serializer = AthleteSerializer(athlete)
return Response(serializer.data)
test.py:
def test_view_athlete(self):
tmp = Athlete.objects.order_by('?')[0]
request = self.factory.get('/_api/v1/athletes/' + str(tmp.id))
request.user = AnonymousUser()
response = ViewAthlete.as_view()(request)
self.assertEquals(response.data.id, tmp.id)
I keep getting the following error:
Traceback (most recent call last): File "/tests.py", line 44, in test_view_athlete response = ViewAthlete.as_view()(request)
File "/venv/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view return view_func(*args, **kwargs)
File "/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view return self.dispatch(request, *args, **kwargs)
File "/venv/lib/python3.5/site-packages/rest_framework/views.py", line 474, in dispatch response = self.handle_exception(exc)
File "/venv/lib/python3.5/site-packages/rest_framework/views.py", line 471, in dispatch response = handler(request, *args, **kwargs) TypeError: get() missing 1 required positional argument: 'id'
To my understanding, the problem is that, there is no id
parameter passed to get
function of ViewAthelete
view class. What is the reason for this? In development environment (not testing), it displays the data but testing environment doesn't recognize the arguments from the route.
AFAIK urlpatterns
are considered when testing through the full django request stack, e.g.: through django.test.Client
, using it's get
/post
methods
When testing your view directly (MyView.as_view()(request)
) the whole url resolver logic is bypassed, and then the args
/kwargs
need to be supplied by the caller (e.g.: MyView.as_view()(request, 'arg1', 'arg2', id='34')
)
As zsepi says, your URLs aren't used here. To avoid repeating the arguments, rather than calling the view directly you could use the test client to "call" the URL: another advantage of doing this is that the middleware runs, so you don't need to assign the user attribute separately.
response = self.client.get('/_api/v1/athletes/' + str(tmp.id))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With