2013-01-08 56 views
2

我正在寫一些模型的約束,如unique=Trueblank=Falsenull=False。我正在試着用鼻子爲模型寫測試。不過,如果我寫這樣一個測試:正確的方式來單元測試沒有交易錯誤的Django模型

from job_sites.models import Site, SiteType 

@raises(IntegrityError) 
def test_empty_site(): 
    s = Site() 
    s.save() 

@raises(IntegrityError) 
def test_empty_site_type(): 
    st = SiteType() 
    st.save() 

我得到一個DatabaseError這樣的: DatabaseError: current transaction is aborted, commands ignored until end of transaction block它運行的第一個考驗。

當我期待錯誤時,運行DJango模型測試的正確方法是什麼?

僅供參考,模型是這樣的:

class SiteType(models.Model): 
    site_type_id = models.AutoField(primary_key=True) 
    site_type = models.CharField(max_length=32, unique=True, blank=False, null=False, default=None) 
    site_type_abbrev = models.CharField(max_length=32, blank=True) 

    class Meta: 
     db_table = u'site_types' 

class Site(models.Model): 
    site_id = models.AutoField(primary_key=True, blank=False, null=False, db_index=True) 
    site_name = models.CharField(max_length=128, blank=False, null=False, db_index=True) 
    site_type = models.ForeignKey(SiteType, blank=True, null=True) 
    date_entered = models.DateTimeField(auto_now_add=True) 

    class Meta: 
     db_table = u'sites' 

我的約束和缺省值是這樣的:

ALTER TABLE site_types ADD CONSTRAINT site_types_site_type_name_minlen CHECK (char_length(site_type) > 0); 
ALTER TABLE sites ALTER COLUMN date_entered SET DEFAULT now(); 
ALTER TABLE sites ADD CONSTRAINT sites_site_name_minlen CHECK (char_length(site_name) > 0); 

回答

1

而不是使用鼻的簡短測試定義的,你應該創建你的測試爲子Django的TestCase的類。這樣,您的數據庫等將在運行時爲您設置和配置,並且所有交易內容都將被神奇地照顧。

有如何寫在Django的項目測試的概述:https://docs.djangoproject.com/en/dev/topics/testing/overview/

的你想要做什麼看起來像等價的:

from django.db import IntegrityError 
from django.utils import unittest 
from job_sites.models import Site, SiteType 

class TestMyStuff(unittest.TestCase): 

    def test_empty_site(self): 
     s = Site() 
     assertRaises(IntegrityError, s.save()) 

    def test_empty_site_type(self): 
     st = SiteType() 
     assertRaises(IntegrityError, st.save()) 

(聲明:我沒有實際上運行此代碼,因此它可能無法正常工作。)

但是,測試這種事情可能是浪費時間。這裏測試的唯一邏輯是Django內部的,所以你沒有通過測試來了解你的應用程序。

+0

我會試試這個。然而,測試這個並不是浪費時間,因爲我的約束是在數據庫級別實現的,而且我需要知道數據庫模式對我的應用程序是正確的。我已經在這種自動生成的代碼中發現了一些錯誤。 – JohnWoltman

+1

您發佈的測試類型不適用於PostgreSQL數據庫。在第一個IntegrityError被拋出後,下一次嘗試調用save()將導致與我原來的問題相同的DatabaseError。必須有一些可接受的方式來使用postgres進行單元測試。 – JohnWoltman

+0

我可以看到你的模型定義嗎?當你說你的「約束是在數據庫級別上實現的」時,我不確定你的意思。你是連接到一個預先存在的數據庫還是什麼? – jscn

相關問題