2010-05-15 2 views
18

J'ai le cas de test django suivant qui me donne des erreurs:Problèmes d'utilisation modèle de l'utilisateur dans l'unité de django teste

class MyTesting(unittest.TestCase): 
    def setUp(self): 
     self.u1 = User.objects.create(username='user1') 
     self.up1 = UserProfile.objects.create(user=self.u1) 

    def testA(self): 
     ... 

    def testB(self): 
     ... 

Quand je lance mes tests, testA va passer avec succès mais avant testB commence, je reçois le texte suivant erreur:

IntegrityError: column username is not unique 

il est clair qu'il essaie de créer self.u1 avant chaque test et de trouver qu'il existe déjà dans la base de données. Comment puis-je le nettoyer correctement après chaque test afin que les cas suivants fonctionnent correctement?

Répondre

27

setUp et tearDown Les méthodes sur Unittests sont appelées avant et après chaque test. Définissez la méthode tearDown qui supprime l'utilisateur créé.

class MyTesting(unittest.TestCase): 
    def setUp(self): 
     self.u1 = User.objects.create(username='user1') 
     self.up1 = UserProfile.objects.create(user=self.u1) 

    def testA(self): 
     ... 

    def tearDown(self): 
     self.up1.delete() 
     self.u1.delete() 

Je conseillerais aussi à create user profiles utilisant le signal post_save sauf si vous voulez vraiment créer un profil d'utilisateur manuellement pour chaque utilisateur.

Suivi sur le commentaire de suppression:

De Django docs:

When Django deletes an object, it emulates the behavior of the SQL constraint ON DELETE CASCADE -- in other words, any objects which had foreign keys pointing at the object to be deleted will be deleted along with it.

Dans votre cas, le profil utilisateur est POINTAGE à l'utilisateur de sorte que vous devez supprimer l'utilisateur d'abord supprimer le profil au en même temps.

+0

Merci! Le problème que j'ai maintenant est que quand je supprime up1, la suppression ne cascade pas et supprime également u1, même si j'ai spécifié User comme une clé étrangère de UserProfile. par exemple. 'user = models.ForeignKey (User, unique = True)' – theycallmemorty

+0

En fait, vous devez supprimer l'utilisateur afin de cascader et supprimer le profil de l'utilisateur en une seule fois, ou vous pouvez supprimer le profil de l'utilisateur d'abord, puis l'utilisateur. –

+0

Bah ... J'ai lu ça pas dans les docs mais pour une raison inconnue, je me suis demandé quelle direction indiquait la clé étrangère ... – theycallmemorty

2

Précisément, setUp existe pour le but précis de courir une fois avant chaque cas de test.

La méthode inverse, celui qui exécute une fois après chaque cas de test, est nommé tearDown: c'est où vous supprimez self.u1 etc (probablement en appelant simplement self.u1.delete(), à moins que vous avez complémentaires exigences de nettoyage spécialisées en plus de tout supprimer l'objet).

8

Si vous souhaitez que django vider automatiquement la base de données de test après chaque test, vous devez étendre django.test.TestCase, PAS django.utils.unittest.TestCase (comme vous le faites actuellement). Il est recommandé de vider la base de données après chaque test afin d'être sûr que les tests sont cohérents, mais notez que vos tests seront plus lents avec cette surcharge supplémentaire.

Voir le AVERTISSEMENT section dans le "Writing Tests" Django Docs.