2009-08-20 38 views
7

Kann mir bitte jemand erklären, wie man Postgres DB-Fehler, insbesondere IntegrityError, richtig testet. Zum Beispiel habe ich nächsten 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) 

Hier fängt es die IntegrityError aber dann werden alle Operationen fehlschlagen, weil das ist, wie postgres funktioniert, ok. Ich sehe in Dokumenten, dass ich transaction.rollback() verwenden kann, aber wo: in test oder in save() -Methode?

Auch mag ich nicht die Idee Rollbacks von Hand zu schreiben, warum kann Django nicht einfach versuchen zu speichern, und wenn es fehlschlägt - geben Sie mir IntegrityError und lassen Sie mich weiter arbeiten.

Ich bin mit django 1.1

Antwort

2

Sie die save() Methode nicht ändern, da Sie es haben wollen sich unter normalen Operationen fortpflanzen. Sie sollten die Ausnahme in Ihrer Test-Klasse abfangen und dort einen Rollback durchführen (beachten Sie, dass Sie TransactionalTestCase von der normalen TestCase ableiten müssen, da Sie Transaktionen testen).

+0

Ok danke. Also im Live-Code wird alles in Ordnung sein, nachdem IntegrityError abgefangen wurde? Oder sollte ich da noch explizit zurückrollen? –

+0

Sie sollten es vermeiden, IntegrityError jemals in Ihrem eigenen Code zu verursachen und alle SQL-Fehler als Fehler zu behandeln. Sie sollten also vor einer Änderung prüfen, ob diese Änderung sinnvoll ist. Wenn Sie feststellen, dass die Änderung nicht vorgenommen werden kann, können Sie das Problem zurücksetzen und dem Benutzer melden. Oder Sie können die Änderung überspringen oder stattdessen eine andere Änderung vornehmen. –

2

nicht zu 100% sicher, dass diese gültig ist, aber Sie tun können:

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

danke, ich werde das versuchen. Aber ehrlich gesagt, das ist hässlich :) –

Verwandte Themen