2017-04-19 79 views
0

這裏是我的看法(簡體):如何測試在Django中使用post請求的視圖?

@login_required(login_url='/try_again') 
def change_bar(request): 
    foo_id = request.POST['fid'] 
    bar_id = request.POST['bid'] 
    foo = models.Foo.objects.get(id=foo_id) 
    if foo.value > 42: 
      bar = models.Bar.objects.get(id=bar_id) 
      bar.value = foo.value 
      bar.save() 
    return other_view(request) 

現在,我想,以檢查是否這種觀點工作正常(在這個簡化的模型,如果欄實例值發生變化時,它應該)。我該如何解決它?

+0

你可以嘗試把「打印」語句之間的代碼,看看是否正確的值保存。也可以使用「過濾」和「更新」方法來更新,而不是使用「get」查詢然後保存(bar.save)。 – badiya

回答

1

我打算假設你的意思是自動化測試,而不是僅僅檢查發佈請求是否工作。如果你的意思是後者,只需通過執行請求並在shell或管理員中檢查相關的FooBar的值來檢查。

有關發送POST請求的最佳方法是使用Client。假設視圖的名稱爲my_view

from django.test import Client 
from django.urls import reverse 

c = Client() 
c.post(reverse(`my_view`, data={'fid':43, `bid`:20} 

但你仍然需要在數據庫中的一些初始數據,並且您需要檢查是否要作出你所期望的變化被推出的。在這裏,你可以使用一個TestCase

from django.test import TestCase, Client 
from django.urls import reverse 

FooBarTestCase(TestCase): 

def setUp(self): 
    # create some foo and bar data, using foo.objects.create etc 
    # this will be run in between each test - the database is rolled back in between tests 

def test_bar_not_changed(self): 
    # write a post request which you expect not to change the value 
    # of a bar instance, then check that the values didn't change 
    self.assertEqual(bar.value, old_bar.value) 

def test_bar_changes(self): 
    # write a post request which you expect to change the value of 
    # a bar instance, then assert that it changed as expected 
    self.assertEqual(foo.value, bar.value) 

,我覺得製作設置了一些數據,以執行測試更容易爲FactoryBoy有用的庫。當爲了測試目的而創建FooBar的新實例時,它減少了樣板。另一種選擇是編寫燈具,但如果您的模型發生變化,我發現靈活性較差。

我還建議this book如果你想知道更多關於python測試。它是以django爲導向的,但這些原則適用於其他框架和上下文。

編輯:約factoryboy和鏈接添加諮詢預訂

+1

非常感謝:)我設法讓這個測試工作! 我不得不添加'from django.contrib.auth.models import User ### self.user = User.objects.create_user(username ='abc',password ='abc')### c.login(username ='abc',password ='abc')'滿足'@ login_required'。還發現'self.assertEqual(self.bar.value,good_value)'由於某種原因不起作用(這是我在'setUp(self)'中創建的'bar')。必須使用'self.assertEqual(Bar.objects.get(id = self.bid).value,good_value)'而不是(獲得相同的(?)欄)。 – Jecke

+1

啊好,很高興它解決了! 'self.assertEqual(Bar.objects.get(id = self.bid).value,good_value)'從數據庫中重新檢索你的'Bar'對象,這意味着它是'相同的'Bar'(因爲它具有相同的主鍵),但它會通過發出您的'POST'請求​​所做的更改進行更新。你可以通過調用'self.bar.refresh_from_db()'來實現同樣的目的,它用來自數據庫的最新信息更新你的python對象'self.bar'。 – FraserES

0

你可以嘗試在代碼之間加上「print」語句,看看是否保存了正確的值。也可以使用「過濾」和「更新」方法來更新,而不是使用「get」查詢並保存(bar.save())。

@login_required(login_url='/try_again') 
def change_bar(request): 
foo_id = request.POST['fid'] 
bar_id = request.POST['bid'] 
foo = models.Foo.objects.get(id=foo_id) 
if foo.value > 42: 
     models.Bar.objects.filter(id=bar_id).update(value=foo.value) 
     #bar.value = foo.value 
     #bar.save() 
return other_view(request) 
+0

感謝.update()方法。至於測試,我在考慮UnitTests,而不僅僅是「手工檢查」。 – Jecke