2009-08-20 7 views
7

Quelqu'un peut-il m'expliquer comment tester correctement les erreurs Postgres DB, en particulier IntegrityError. Par exemple, j'ai test suivant: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) 

Ici, il attrape le IntegrityError mais toutes les opérations échouera, parce que comment fonctionne Postgres, ok. Je vois dans les docs que je peux utiliser transaction.rollback() mais où: dans test ou dans la méthode save()?

Aussi, je n'aime pas l'idée d'écrire des rollbacks à la main, pourquoi django ne peut pas simplement essayer d'enregistrer, et si elle échoue - donnez-moi IntegrityError et laissez-moi continuer à travailler.

J'utilise django 1.1

Répondre

2

Ne pas modifier la méthode de sauvegarde(), puisque vous le souhaitez se propager à travers des opérations normales. Vous devriez attraper l'exception dans votre classe de test et revenir en arrière (notez que puisque vous testez des transactions, vous devez sous-classer TransactionalTestCase au lieu de TestCase normal).

+0

Ok merci. Donc, dans le code en direct, tout ira bien après avoir attrapé IntegrityError? Ou devrais-je toujours revenir en arrière explicitement? –

+0

Vous devriez éviter de provoquer IntegrityError dans votre propre code, et traiter toute erreur SQL comme un bug. Donc, vous devriez vérifier avant d'essayer une modification si cette modification sera sensible. Si vous constatez que la modification ne peut pas être effectuée, vous pouvez revenir en arrière et signaler le problème à l'utilisateur. Ou vous pouvez décider d'ignorer la modification ou de faire une modification différente à la place. –

2

pas à 100% sûr que ce soit valide, mais vous pouvez faire:

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

merci, je vais essayer. Mais franchement parlant, c'est moche :) –