2009-08-20 17 views
7

Czy ktoś może mi wyjaśnić jak poprawnie testować błędy DB PostgreSQL, szczególnie IntegrityError. Na przykład mam kolejny test:django Postgres IntegrityError

class TestSlugs(TestCase): 
    # This slug must be unique 
    b = BookPublisher(slug=self.duplicate_slug) 
    self.assertRaises(IntegrityError, b.save) 

    #check if there's only one BookPublisher 
    self.assertEquals(BookPublisher.objects.count(), 1) 

Tutaj łapie IntegrityError ale wtedy wszystkie operacje zakończy się niepowodzeniem, ponieważ to jak PostgreSQL prace, ok. Widzę w dokumentach, że mogę używać transakcji transaction.rollback(), ale gdzie: w teście lub w metodzie save()?

Nie podoba mi się również pomysł ręcznego wycofywania zmian, dlaczego django nie może po prostu spróbować zapisać, a jeśli się nie powiedzie - daj mi IntegrityError i pozwól mi kontynuować pracę.

Używam Django 1.1

Odpowiedz

2

Nie zmienia metodę save(), ponieważ chcesz go propagować w ramach normalnych operacji. Powinieneś wychwycić wyjątek w swojej klasie Test i tam wycofać (zauważ, że skoro testujesz transakcje, musisz podklasę TransactionalTestCase zamiast normalnej TestCase).

+0

Ok dzięki. Czy w żywym kodzie wszystko będzie dobrze po złapaniu IntegrityError? Czy powinienem tam nadal wycofywać? –

+0

Powinieneś unikać kiedykolwiek powodując IntegrityError we własnym kodzie i traktować jakikolwiek błąd SQL jako błąd. Powinieneś więc sprawdzić przed próbą modyfikacji, czy ta modyfikacja będzie sensowna. Jeśli okaże się, że modyfikacji nie można wprowadzić, możesz wycofać i zgłosić problem użytkownikowi. Możesz też zrezygnować z modyfikacji lub wprowadzić inną modyfikację. –

2

nie w 100% pewien, że to jest ważne, ale można zrobić:

def save(self): 
    transaction.commit() 
    try: 
     super(MyModel, self).save() 
    except IntegrityError: 
     transaction.rollback() 
    else: 
     transaction.commit() 
+0

dzięki, spróbuję tego. Ale szczerze mówiąc, to jest brzydkie :) –