From e4cb70719e59daba0b8942fa91cbe472a0613312 Mon Sep 17 00:00:00 2001 From: JasonHomeWorkstationUbuntu Date: Mon, 9 Nov 2020 12:03:16 +1100 Subject: [PATCH] 5.7.1 Better Unit Testing Practice: Each Test Should Test One Thing --- textbook/chap5.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/textbook/chap5.md b/textbook/chap5.md index e0f120f..38546f1 100644 --- a/textbook/chap5.md +++ b/textbook/chap5.md @@ -280,4 +280,61 @@ def home_page(request): return render(request=request, template_name='home.html', context={ 'new_item_text': request.POST.get('item_text', ''), }) +``` + +## 5.7 Redirect After a POST + +A view func has 2 jobs: +1. Processing user input (save to database) +2. Returning an appropriate response + +2nd one is our target in this section + +"Always redirect after a POST", change test case to save a POST request. So redirect back to home page, instead of rendering a response with item in it + +```python + def test_can_save_a_POST_request(self): + response = self.client.post('/', data={'item_text': 'A new list item'}) + + self.assertEqual(Item.objects.count(), 1) + new_item = Item.objects.first() + self.assertEqual(new_item.text, 'A new list item') + + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], '/') +``` + +* QUES: What mean redirect? +* ANS: After sending POST, the returned response does not contain `.content` that rendered by a template, instead it's HTTP redirect that point to another URL + +Modify `views.py` to pass this UT + +```python +def home_page(request): + if request.method == 'POST': + Item.objects.create(text=request.POST['item_text']) # Processing user input + return redirect('/') # Redirect back to home.html + + return render(request=request, template_name='home.html') +``` + +### 5.7.1 Better Unit Testing Practice: Each Test Should Test One Thing + +Note: good UT practice is that each test should only test one thing. + +So, separate the test code into two: + +```python + def test_can_save_a_POST_request(self): + self.client.post('/', data={'item_text': 'A new list item'}) + + self.assertEqual(Item.objects.count(), 1) + new_item = Item.objects.first() + self.assertEqual(new_item.text, 'A new list item') + + def test_redirects_after_POST(self): + response = self.client.post('/', data={'item_text': 'A new list item'}) + + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], '/') ``` \ No newline at end of file