2016-08-16 7 views
0

電子メールとストアのunique_together制約があります。私はユニーク制約をテストするために次のコードを使用しました。私はassertRaiseでテストに合格することを期待していますが、結果は反対です。ここで私は何が欠けているのですか? 1.8:IntegrityError UNIQUE制約のテストに失敗しました

from django.db.backends.sqlite3.base import IntegrityError 

class TestUserModel(TestCase): 
    def setUp(self): 
     self.store1 = Store.objects.create(name='store1') 
     self.store2 = Store.objects.create(name='store2') 

    def multiple_user_with_same_email_and_store(self): 
     data1 = dict(email="[email protected]", password="a", store=self.store1) 
     data2 = dict(email="[email protected]", password="abc", store=self.store1) 
     self.user1 = User.objects.create(**data1) 
     user2 = User(**data2) 
     self.assertRaises(IntegrityError, user2.save) 

トレースバック

Creating test database for alias 'default'... 
E 
====================================================================== 
ERROR: multiple_user_with_same_email_and_store (user.tests.test_models.TestUserModel) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/ram/nk/project/helper/helper/user/tests/test_models.py", line 25, in multiple_user_with_same_email_and_store 
    self.assertRaises(IntegrityError, user2.save) 
    File "/usr/lib/python2.7/unittest/case.py", line 473, in assertRaises 
    callableObj(*args, **kwargs) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/models/base.py", line 734, in save 
    force_update=force_update, update_fields=update_fields) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/models/base.py", line 762, in save_base 
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/models/base.py", line 846, in _save_table 
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/models/base.py", line 885, in _do_insert 
    using=using, raw=raw) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/models/manager.py", line 127, in manager_method 
    return getattr(self.get_queryset(), name)(*args, **kwargs) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/models/query.py", line 920, in _insert 
    return query.get_compiler(using=using).execute_sql(return_id) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 974, in execute_sql 
    cursor.execute(sql, params) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/utils.py", line 97, in __exit__ 
    six.reraise(dj_exc_type, dj_exc_value, traceback) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/home/ram/.virtual/helper/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 318, in execute 
    return Database.Cursor.execute(self, query, params) 
IntegrityError: UNIQUE constraint failed: user_user.email, user_user.store_id 


    ---------------------------------------------------------------------- 
    Ran 1 test in 0.003s 

    FAILED (errors=1) 

Userモデルは

class AbstractUser(auth_models.AbstractBaseUser, PermissionsMixin): 

    email = models.EmailField(_('email address')) 
    store = models.ForeignKey(Store, verbose_name=_('Store Name'), null=True) 
    first_name = models.CharField(_('First name'), max_length=255, blank=True) 
    last_name = models.CharField(_('Last name'), max_length=255, blank=True) 
    is_staff = models.BooleanField(
      _('Staff status'), default=False, 
      help_text=_('Designates whether the user can log into this admin ' 
         'site.')) 
    is_active = models.BooleanField(
      _('Active'), default=True, 
      help_text=_('Designates whether this user should be treated as ' 
         'active. Unselect this instead of deleting accounts.')) 
    date_joined = models.DateTimeField(_('date joined'), 
             default=timezone.now) 

    objects = UserManager() 

    USERNAME_FIELD = 'email' 
    REQUIRED_FIELDS = ['store'] 

    class Meta: 
     abstract = True 
     verbose_name = _('User') 
     verbose_name_plural = _('Users') 
     unique_together = ('email', 'store') 

とのUserManager

class UserManager(auth_models.BaseUserManager): 
    def create_user(self, store, email, password=None, **extra_fields): 
     """ 
     Creates and saves a User with the given email and 
     password. 
     """ 
     now = timezone.now() 
     if not email: 
      raise ValueError('The given email must be set') 
     email = UserManager.normalize_email(email) 
     try: 
      with transaction.atomic(): 
       store, created = Store.objects.get_or_create(name=store) 
       user = self.model(email=email, store=store, is_staff=False, is_active=True, is_superuser=False, 
         last_login=now, date_joined=now, **extra_fields) 
       user.set_password(password) 
       user.save(using=self._db) 
     except Error as e: 
      logging.ERROR(e) 
      raise Error("Internal Error: Unable to create user") 
     return user 

    def create_superuser(self, store, email, password, **extra_fields): 
     u = self.create_user(store, email, password, **extra_fields) 
     u.is_staff = True 
     u.is_active = True 
     u.is_superuser = True 
     u.save(using=self._db) 
     return u 

    def create_staffuser(self, store, email, password, **extra_fields): 
     u = self.create_user(store, email, password, **extra_fields) 
     u.is_staff = True 
     u.is_active = True 
     u.is_superuser = False 
     u.save(using=self._db) 
     return u 

従う版としてあるAbstractUserを(他の何もユーザに添加しない)、延びています

+0

はあなた 'User'モデルの定義(フィールドを表示してください可能性があり、もしあれば、__init__メソッドと完全なエラースタックトレース – zsepi

+0

unique_togetherはタプルのタプルでなければなりません(この場合、電子メールはそれ自身で一意であり、ストア自体は一意です)。https:// docs.djangoproject.com/en/1.10/ref/models/options/#django.db.models.Options.unique_togetherしかし、なぜそれが期待される行で失敗していないのか説明していません(ここでは完全なエラートレースバックがhelp) – zsepi

+0

テストでは、どこから 'IntegrityError'がインポートされましたか? – zsepi

答えて

2

エラーが正しい行(assertRaises)で発生していますが、ここでは2種類の異なる種類のIntegrityErrorクラスが存在していると思われます.1つはテストによってインポートされ、もう1つはデータベースによって生成されたクラスですバックエンド。

例:django.db.backends.postgresql.base.IntegrityErrorは、django.db.backends.sqlite3.base.IntegrityErrorと同じではありません。その上で、Djangoの例外ラッパーdjango.db.utils.IntegrityError

問題は、コンテキストマネージャとしてself.assertRaisesを使用することにより、デバッグ、検証することができますがあります:

with self.assertRaises(Exception) as raised: # top level exception as we want to figure out its exact type 
    user2.save() 
self.assertEqual(IntegrityError, type(raised.exception)) # if it fails, we'll get the correct type to import 
関連する問題