简体   繁体   English

测试用户模型是否具有密码的正确方法

[英]Correct way to test if a User model has a password

I have this models 我有这个模特

from django.db import models
from django.contrib.auth.models import AbstractUser

class Account(AbstractUser):
    last_updated = models.DateTimeField(default=datetime.now, blank=False, null=False)


class User(Account):
    security_question = models.TextField(blank=True)
    security_answer = models.CharField(max_length=50, blank=True)

and this simple test case: 这个简单的测试用例:

from django import test
from myapp import models


class UserTestCase(test.TestCase):

    def test_user_password_cannot_be_empty(self):
        def create_user_without_password():
            models.User.objects.create(
                username='usr2',
                first_name='Name',
                last_name='Name2',
                email='me@email.com'
        )

        # should throw an error
        self.assertRaises(
            Exception,
            create_user_without_password
        )

The test should pass as password is a mandatory field, yet by running python manage.py test --pattern="tests_*.py" I get 测试应该通过,因为密码是必填字段,但是通过运行python manage.py test --pattern="tests_*.py"我得到了

====================================================================== ================================================== ====================

FAIL: test_user_password_cannot_be_empty (myapp.tests_user_testcase.UserTestCase) AssertionError: Exception not raised by create_user_without_password 失败:test_user_password_cannot_be_empty(myapp.tests_user_testcase.UserTestCase)AssertionError:create_user_without_password未引发异常


I guess I'm testing it wrongly. 我想我测试错了。 What is the correct way? 正确的方法是什么?


Specs: 眼镜:

  • Python 3.6.1 的Python 3.6.1
  • Django 2.1.1 Django 2.1.1
  • Windows 10 Windows 10

You are probably running into the nature that Django Models will save blank=False fields without error. 您可能已经遇到了Django模型将无错误地保存blank=False字段的本质。 You can find lengthy debates about it. 您可以找到有关它的冗长辩论。 To enforce it at the model.save level, you have to overwrite the save method. 要在model.save级别实施它,您必须覆盖save方法。

def save(self, *args, **kwargs):
    self.full_clean()
    super().save(*args, **kwargs)

Your code is correct, but password is a CharField so you're always able to create a user without a password this way ( CharField gets always set to empty string by default even if blank=False ). 您的代码是正确的,但是passwordCharField因此您始终可以通过这种方式创建没有密码的用户(默认情况下,即使blank=False CharField始终设置为空字符串)。

You are also correctly calling self.assertRaises , which takes a callable . 您还正确地调用了带callable的 self.assertRaises So it would be wrong to do self.assertRaises(Exception, create_user_without_password()) because that would indeed raise an exception because your function would be called twice: the exception would be NoneType is not callable. 因此执行self.assertRaises(Exception, create_user_without_password())是错误的,因为这确实会引发异常,因为您的函数将被调用两次:异常为NoneType不可调用。 Your test would pass, but not for the correct reason! 您的测试会通过,但原因不正确!

The default Django model AbstractBaseUser doesn't force password to be set. 默认的Django模型AbstractBaseUser不会强制设置password The forms to create a user do this. 创建用户的表单可以执行此操作。 The reason is, you may have a system where users are first created by other users without password so they can set the password themselves. 原因是,您可能拥有一个系统,在该系统中,其他用户首先会创建没有密码的用户,以便他们可以自己设置密码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM