| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
 | <!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta charset="utf-8">
  <title>Testing - Django REST framework</title>
  <link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
  <link rel="canonical" href="http://www.django-rest-framework.org/api-guide/testing/" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="Django, API, REST, Testing">
  <meta name="author" content="Tom Christie">
  <!-- Le styles -->
  <link href="../../css/prettify.css" rel="stylesheet">
  <link href="../../css/bootstrap.css" rel="stylesheet">
  <link href="../../css/bootstrap-responsive.css" rel="stylesheet">
  <link href="../../css/default.css" rel="stylesheet">
  <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
  <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
  <script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-18852272-2']);
    _gaq.push(['_trackPageview']);
    (function() {
      var ga = document.createElement('script');
      ga.type = 'text/javascript';
      ga.async = true;
      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(ga, s);
    })();
  </script>
  <style>
    span.fusion-wrap a {
      display: block;
      margin-top: 10px;
      color: black;
    }
    a.fusion-poweredby {
      display: block;
      margin-top: 10px;
    }
    @media (max-width: 767px) {
      div.promo {
        display: none;
      }
    }
  </style>
</head>
<body onload="prettyPrint()" class="-page">
  <div class="wrapper">
        <div class="navbar navbar-inverse navbar-fixed-top">
      <div class="navbar-inner">
        <div class="container-fluid">
          <a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
          <a class="repo-link btn btn-inverse btn-small " rel="prev" href="../settings">
            Next <i class="icon-arrow-right icon-white"></i>
          </a>
          <a class="repo-link btn btn-inverse btn-small " rel="next" href="../status-codes">
            <i class="icon-arrow-left icon-white"></i> Previous
          </a>
          <a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </a>
          <a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
          <div class="nav-collapse collapse">
            
            <!-- Main navigation -->
            <ul class="nav navbar-nav">
              <li ><a href="/">Home</a></li>
               
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
                <ul class="dropdown-menu">
                  
                  <li >
                    <a href="../../tutorial/quickstart">Quickstart</a>
                  </li>
                  
                  <li >
                    <a href="../../tutorial/1-serialization">1 - Serialization</a>
                  </li>
                  
                  <li >
                    <a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
                  </li>
                  
                  <li >
                    <a href="../../tutorial/3-class-based-views">3 - Class based views</a>
                  </li>
                  
                  <li >
                    <a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
                  </li>
                  
                  <li >
                    <a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
                  </li>
                  
                  <li >
                    <a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
                  </li>
                  
                </ul>
              </li>
                
              <li class="dropdown active">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
                <ul class="dropdown-menu">
                  
                  <li >
                    <a href="../requests">Requests</a>
                  </li>
                  
                  <li >
                    <a href="../responses">Responses</a>
                  </li>
                  
                  <li >
                    <a href="../views">Views</a>
                  </li>
                  
                  <li >
                    <a href="../generic-views">Generic views</a>
                  </li>
                  
                  <li >
                    <a href="../viewsets">Viewsets</a>
                  </li>
                  
                  <li >
                    <a href="../routers">Routers</a>
                  </li>
                  
                  <li >
                    <a href="../parsers">Parsers</a>
                  </li>
                  
                  <li >
                    <a href="../renderers">Renderers</a>
                  </li>
                  
                  <li >
                    <a href="../serializers">Serializers</a>
                  </li>
                  
                  <li >
                    <a href="../fields">Serializer fields</a>
                  </li>
                  
                  <li >
                    <a href="../relations">Serializer relations</a>
                  </li>
                  
                  <li >
                    <a href="../validators">Validators</a>
                  </li>
                  
                  <li >
                    <a href="../authentication">Authentication</a>
                  </li>
                  
                  <li >
                    <a href="../permissions">Permissions</a>
                  </li>
                  
                  <li >
                    <a href="../throttling">Throttling</a>
                  </li>
                  
                  <li >
                    <a href="../filtering">Filtering</a>
                  </li>
                  
                  <li >
                    <a href="../pagination">Pagination</a>
                  </li>
                  
                  <li >
                    <a href="../content-negotiation">Content negotiation</a>
                  </li>
                  
                  <li >
                    <a href="../format-suffixes">Format suffixes</a>
                  </li>
                  
                  <li >
                    <a href="../reverse">Returning URLs</a>
                  </li>
                  
                  <li >
                    <a href="../exceptions">Exceptions</a>
                  </li>
                  
                  <li >
                    <a href="../status-codes">Status codes</a>
                  </li>
                  
                  <li class="active" >
                    <a href=".">Testing</a>
                  </li>
                  
                  <li >
                    <a href="../settings">Settings</a>
                  </li>
                  
                </ul>
              </li>
                
              <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
                <ul class="dropdown-menu">
                  
                  <li >
                    <a href="../../topics/documenting-your-api">Documenting your API</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/browser-enhancements">Browser enhancements</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/browsable-api">The Browsable API</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/third-party-resources">Third Party Resources</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/contributing">Contributing to REST framework</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/2.2-announcement">2.2 Announcement</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/2.3-announcement">2.3 Announcement</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/2.4-announcement">2.4 Announcement</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/release-notes">Release Notes</a>
                  </li>
                  
                  <li >
                    <a href="../../topics/credits">Credits</a>
                  </li>
                  
                </ul>
              </li>
               
            </ul>
            
          </div>
          <!--/.nav-collapse -->
        </div>
      </div>
    </div>
    <div class="body-content">
      <div class="container-fluid">
        <!-- Search Modal -->
        <div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 id="myModalLabel">Documentation search</h3>
          </div>
          <div class="modal-body">
            <!-- Custom google search -->
            <script>
              (function() {
                var cx = '015016005043623903336:rxraeohqk6w';
                var gcse = document.createElement('script');
                gcse.type = 'text/javascript';
                gcse.async = true;
                gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
                  '//www.google.com/cse/cse.js?cx=' + cx;
                var s = document.getElementsByTagName('script')[0];
                s.parentNode.insertBefore(gcse, s);
              })();
            </script>
            <gcse:search></gcse:search>
          </div>
          <div class="modal-footer">
            <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
          </div>
        </div>
        <div class="row-fluid">
          <div class="span3">
            <!-- TODO
            <p style="margin-top: -12px">
              <a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
              <a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
            </p>
          -->
            <div id="table-of-contents">
              <ul class="nav nav-list side-nav well sidebar-nav-fixed">
                
                
                  <li class="main">
                    <a href="#testing">Testing</a>
                  </li>
                  
                
                  <li class="main">
                    <a href="#apirequestfactory">APIRequestFactory</a>
                  </li>
                  
                    <li>
                      <a href="#creating-test-requests">Creating test requests</a>
                    </li>
                  
                    <li>
                      <a href="#forcing-authentication">Forcing authentication</a>
                    </li>
                  
                    <li>
                      <a href="#forcing-csrf-validation">Forcing CSRF validation</a>
                    </li>
                  
                
                  <li class="main">
                    <a href="#apiclient">APIClient</a>
                  </li>
                  
                    <li>
                      <a href="#making-requests">Making requests</a>
                    </li>
                  
                    <li>
                      <a href="#authenticating">Authenticating</a>
                    </li>
                  
                    <li>
                      <a href="#csrf-validation">CSRF validation</a>
                    </li>
                  
                
                  <li class="main">
                    <a href="#test-cases">Test cases</a>
                  </li>
                  
                    <li>
                      <a href="#example">Example</a>
                    </li>
                  
                
                  <li class="main">
                    <a href="#testing-responses">Testing responses</a>
                  </li>
                  
                    <li>
                      <a href="#checking-the-response-data">Checking the response data</a>
                    </li>
                  
                    <li>
                      <a href="#rendering-responses">Rendering responses</a>
                    </li>
                  
                
                  <li class="main">
                    <a href="#configuration">Configuration</a>
                  </li>
                  
                    <li>
                      <a href="#setting-the-default-format">Setting the default format</a>
                    </li>
                  
                    <li>
                      <a href="#setting-the-available-formats">Setting the available formats</a>
                    </li>
                  
                
                
              </ul>
            </div>
          </div>
          <div id="main-content" class="span9">
            
              
                <a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/test.py">
                  <span class="label label-info">test.py</span>
                </a>
              
            
            <h1 id="testing">Testing</h1>
<blockquote>
<p>Code without tests is broken as designed.</p>
<p>— <a href="http://jacobian.org/writing/django-apps-with-buildout/#s-create-a-test-wrapper">Jacob Kaplan-Moss</a></p>
</blockquote>
<p>REST framework includes a few helper classes that extend Django's existing test framework, and improve support for making API requests.</p>
<h1 id="apirequestfactory">APIRequestFactory</h1>
<p>Extends <a href="https://docs.djangoproject.com/en/dev/topics/testing/advanced/#django.test.client.RequestFactory">Django's existing <code>RequestFactory</code> class</a>.</p>
<h2 id="creating-test-requests">Creating test requests</h2>
<p>The <code>APIRequestFactory</code> class supports an almost identical API to Django's standard <code>RequestFactory</code> class.  This means the that standard <code>.get()</code>, <code>.post()</code>, <code>.put()</code>, <code>.patch()</code>, <code>.delete()</code>, <code>.head()</code> and <code>.options()</code> methods are all available.</p>
<pre><code>from rest_framework.test import APIRequestFactory
# Using the standard RequestFactory API to create a form POST request
factory = APIRequestFactory()
request = factory.post('/notes/', {'title': 'new idea'})
</code></pre>
<h4 id="using-the-format-argument">Using the <code>format</code> argument</h4>
<p>Methods which create a request body, such as <code>post</code>, <code>put</code> and <code>patch</code>, include a <code>format</code> argument, which make it easy to generate requests using a content type other than multipart form data.  For example:</p>
<pre><code># Create a JSON POST request
factory = APIRequestFactory()
request = factory.post('/notes/', {'title': 'new idea'}, format='json')
</code></pre>
<p>By default the available formats are <code>'multipart'</code> and <code>'json'</code>.  For compatibility with Django's existing <code>RequestFactory</code> the default format is <code>'multipart'</code>.</p>
<p>To support a wider set of request formats, or change the default format, <a href="#configuration">see the configuration section</a>.</p>
<h4 id="explicitly-encoding-the-request-body">Explicitly encoding the request body</h4>
<p>If you need to explicitly encode the request body, you can do so by setting the <code>content_type</code> flag.  For example:</p>
<pre><code>request = factory.post('/notes/', json.dumps({'title': 'new idea'}), content_type='application/json')
</code></pre>
<h4 id="put-and-patch-with-form-data">PUT and PATCH with form data</h4>
<p>One difference worth noting between Django's <code>RequestFactory</code> and REST framework's <code>APIRequestFactory</code> is that multipart form data will be encoded for methods other than just <code>.post()</code>.</p>
<p>For example, using <code>APIRequestFactory</code>, you can make a form PUT request like so:</p>
<pre><code>factory = APIRequestFactory()
request = factory.put('/notes/547/', {'title': 'remember to email dave'})
</code></pre>
<p>Using Django's <code>RequestFactory</code>, you'd need to explicitly encode the data yourself:</p>
<pre><code>from django.test.client import encode_multipart, RequestFactory
factory = RequestFactory()
data = {'title': 'remember to email dave'}
content = encode_multipart('BoUnDaRyStRiNg', data)
content_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg'
request = factory.put('/notes/547/', content, content_type=content_type)
</code></pre>
<h2 id="forcing-authentication">Forcing authentication</h2>
<p>When testing views directly using a request factory, it's often convenient to be able to directly authenticate the request, rather than having to construct the correct authentication credentials.</p>
<p>To forcibly authenticate a request, use the <code>force_authenticate()</code> method.</p>
<pre><code>factory = APIRequestFactory()
user = User.objects.get(username='olivia')
view = AccountDetail.as_view()
# Make an authenticated request to the view...
request = factory.get('/accounts/django-superstars/')
force_authenticate(request, user=user)
response = view(request)
</code></pre>
<p>The signature for the method is <code>force_authenticate(request, user=None, token=None)</code>.  When making the call, either or both of the user and token may be set.</p>
<p>For example, when forcibly authenticating using a token, you might do something like the following:</p>
<pre><code>user = User.objects.get(username='olivia')
request = factory.get('/accounts/django-superstars/')
force_authenticate(request, user=user, token=user.token)
</code></pre>
<hr />
<p><strong>Note</strong>: When using <code>APIRequestFactory</code>, the object that is returned is Django's standard <code>HttpRequest</code>, and not REST framework's <code>Request</code> object, which is only generated once the view is called.</p>
<p>This means that setting attributes directly on the request object may not always have the effect you expect.  For example, setting <code>.token</code> directly will have no effect, and setting <code>.user</code> directly will only work if session authentication is being used.</p>
<pre><code># Request will only authenticate if `SessionAuthentication` is in use.
request = factory.get('/accounts/django-superstars/')
request.user = user
response = view(request)
</code></pre>
<hr />
<h2 id="forcing-csrf-validation">Forcing CSRF validation</h2>
<p>By default, requests created with <code>APIRequestFactory</code> will not have CSRF validation applied when passed to a REST framework view.  If you need to explicitly turn CSRF validation on, you can do so by setting the <code>enforce_csrf_checks</code> flag when instantiating the factory.</p>
<pre><code>factory = APIRequestFactory(enforce_csrf_checks=True)
</code></pre>
<hr />
<p><strong>Note</strong>: It's worth noting that Django's standard <code>RequestFactory</code> doesn't need to include this option, because when using regular Django the CSRF validation takes place in middleware, which is not run when testing views directly.  When using REST framework, CSRF validation takes place inside the view, so the request factory needs to disable view-level CSRF checks.</p>
<hr />
<h1 id="apiclient">APIClient</h1>
<p>Extends <a href="https://docs.djangoproject.com/en/dev/topics/testing/overview/#module-django.test.client">Django's existing <code>Client</code> class</a>.</p>
<h2 id="making-requests">Making requests</h2>
<p>The <code>APIClient</code> class supports the same request interface as <code>APIRequestFactory</code>.  This means the that standard <code>.get()</code>, <code>.post()</code>, <code>.put()</code>, <code>.patch()</code>, <code>.delete()</code>, <code>.head()</code> and <code>.options()</code> methods are all available.  For example:</p>
<pre><code>from rest_framework.test import APIClient
client = APIClient()
client.post('/notes/', {'title': 'new idea'}, format='json')
</code></pre>
<p>To support a wider set of request formats, or change the default format, <a href="#configuration">see the configuration section</a>.</p>
<h2 id="authenticating">Authenticating</h2>
<h4 id="loginkwargs">.login(**kwargs)</h4>
<p>The <code>login</code> method functions exactly as it does with Django's regular <code>Client</code> class.  This allows you to authenticate requests against any views which include <code>SessionAuthentication</code>.</p>
<pre><code># Make all requests in the context of a logged in session.
client = APIClient()
client.login(username='lauren', password='secret')
</code></pre>
<p>To logout, call the <code>logout</code> method as usual.</p>
<pre><code># Log out
client.logout()
</code></pre>
<p>The <code>login</code> method is appropriate for testing APIs that use session authentication, for example web sites which include AJAX interaction with the API.</p>
<h4 id="credentialskwargs">.credentials(**kwargs)</h4>
<p>The <code>credentials</code> method can be used to set headers that will then be included on all subsequent requests by the test client.</p>
<pre><code>from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient
# Include an appropriate `Authorization:` header on all requests.
token = Token.objects.get(user__username='lauren')
client = APIClient()
client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)
</code></pre>
<p>Note that calling <code>credentials</code> a second time overwrites any existing credentials.  You can unset any existing credentials by calling the method with no arguments.</p>
<pre><code># Stop including any credentials
client.credentials()
</code></pre>
<p>The <code>credentials</code> method is appropriate for testing APIs that require authentication headers, such as basic authentication, OAuth1a and OAuth2 authentication, and simple token authentication schemes.</p>
<h4 id="force_authenticateusernone-tokennone">.force_authenticate(user=None, token=None)</h4>
<p>Sometimes you may want to bypass authentication, and simple force all requests by the test client to be automatically treated as authenticated.</p>
<p>This can be a useful shortcut if you're testing the API but don't want to have to construct valid authentication credentials in order to make test requests.</p>
<pre><code>user = User.objects.get(username='lauren')
client = APIClient()
client.force_authenticate(user=user)
</code></pre>
<p>To unauthenticate subsequent requests, call <code>force_authenticate</code> setting the user and/or token to <code>None</code>.</p>
<pre><code>client.force_authenticate(user=None)
</code></pre>
<h2 id="csrf-validation">CSRF validation</h2>
<p>By default CSRF validation is not applied when using <code>APIClient</code>.  If you need to explicitly enable CSRF validation, you can do so by setting the <code>enforce_csrf_checks</code> flag when instantiating the client.</p>
<pre><code>client = APIClient(enforce_csrf_checks=True)
</code></pre>
<p>As usual CSRF validation will only apply to any session authenticated views.  This means CSRF validation will only occur if the client has been logged in by calling <code>login()</code>.</p>
<hr />
<h1 id="test-cases">Test cases</h1>
<p>REST framework includes the following test case classes, that mirror the existing Django test case classes, but use <code>APIClient</code> instead of Django's default <code>Client</code>.</p>
<ul>
<li><code>APISimpleTestCase</code></li>
<li><code>APITransactionTestCase</code></li>
<li><code>APITestCase</code></li>
<li><code>APILiveServerTestCase</code></li>
</ul>
<h2 id="example">Example</h2>
<p>You can use any of REST framework's test case classes as you would for the regular Django test case classes.  The <code>self.client</code> attribute will be an <code>APIClient</code> instance.</p>
<pre><code>from django.core.urlresolvers import reverse
from rest_framework import status
from rest_framework.test import APITestCase
class AccountTests(APITestCase):
    def test_create_account(self):
        """
        Ensure we can create a new account object.
        """
        url = reverse('account-list')
        data = {'name': 'DabApps'}
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data, data)
</code></pre>
<hr />
<h1 id="testing-responses">Testing responses</h1>
<h2 id="checking-the-response-data">Checking the response data</h2>
<p>When checking the validity of test responses it's often more convenient to inspect the data that the response was created with, rather than inspecting the fully rendered response.</p>
<p>For example, it's easier to inspect <code>response.data</code>:</p>
<pre><code>response = self.client.get('/users/4/')
self.assertEqual(response.data, {'id': 4, 'username': 'lauren'})
</code></pre>
<p>Instead of inspecting the result of parsing <code>response.content</code>:</p>
<pre><code>response = self.client.get('/users/4/')
self.assertEqual(json.loads(response.content), {'id': 4, 'username': 'lauren'})
</code></pre>
<h2 id="rendering-responses">Rendering responses</h2>
<p>If you're testing views directly using <code>APIRequestFactory</code>, the responses that are returned will not yet be rendered, as rendering of template responses is performed by Django's internal request-response cycle.  In order to access <code>response.content</code>, you'll first need to render the response.</p>
<pre><code>view = UserDetail.as_view()
request = factory.get('/users/4')
response = view(request, pk='4')
response.render()  # Cannot access `response.content` without this.
self.assertEqual(response.content, '{"username": "lauren", "id": 4}')
</code></pre>
<hr />
<h1 id="configuration">Configuration</h1>
<h2 id="setting-the-default-format">Setting the default format</h2>
<p>The default format used to make test requests may be set using the <code>TEST_REQUEST_DEFAULT_FORMAT</code> setting key.  For example, to always use JSON for test requests by default instead of standard multipart form requests, set the following in your <code>settings.py</code> file:</p>
<pre><code>REST_FRAMEWORK = {
    ...
    'TEST_REQUEST_DEFAULT_FORMAT': 'json'
}
</code></pre>
<h2 id="setting-the-available-formats">Setting the available formats</h2>
<p>If you need to test requests using something other than multipart or json requests, you can do so by setting the <code>TEST_REQUEST_RENDERER_CLASSES</code> setting.</p>
<p>For example, to add support for using <code>format='yaml'</code> in test requests, you might have something like this in your <code>settings.py</code> file.</p>
<pre><code>REST_FRAMEWORK = {
    ...
    'TEST_REQUEST_RENDERER_CLASSES': (
        'rest_framework.renderers.MultiPartRenderer',
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.YAMLRenderer'
    )
}
</code></pre>
          </div>
          <!--/span-->
        </div>
        <!--/row-->
      </div>
      <!--/.fluid-container-->
    </div>
    <!--/.body content-->
    <div id="push"></div>
  </div>
  <!--/.wrapper -->
  <footer class="span12">
    <p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
    </p>
  </footer>
  <!-- Le javascript
  ================================================== -->
  <!-- Placed at the end of the document so the pages load faster -->
  <script src="../../js/jquery-1.8.1-min.js"></script>
  <script src="../../js/prettify-1.0.js"></script>
  <script src="../../js/bootstrap-2.1.1-min.js"></script>
  <script>
    //$('.side-nav').scrollspy()
    var shiftWindow = function() {
      scrollBy(0, -50)
    };
    if (location.hash) shiftWindow();
    window.addEventListener("hashchange", shiftWindow);
    $('.dropdown-menu').on('click touchstart', function(event) {
      event.stopPropagation();
    });
    // Dynamically force sidenav to no higher than browser window
    $('.side-nav').css('max-height', window.innerHeight - 130);
    $(function() {
      $(window).resize(function() {
        $('.side-nav').css('max-height', window.innerHeight - 130);
      });
    });
  </script>
</body>
</html>
 |