【问题标题】:How to get message from E11000 DuplicationKeyError?如何从 E11000 Duplicate Key Error 中获取消息?
【发布时间】:2020-08-13 09:36:39
【问题描述】:

所以我正在为一个项目编写单元测试,我正在测试register() 函数。

这里是:

def register():
    # Get information about user
    username = request.get_json().get("username")
    password = request.get_json().get("password")
    name = request.get_json().get("name")
    email = request.get_json().get("email")

    # Put information about user in a tuple
    values = (
        None, 
        username, 
        User.hash_password(password), 
        name,
        email,
        None
    )

    try:
        # Create user and update session
        User(*values).create()
        ActiveUser.logged_in = True
        ActiveUser.username = username
        info_log.info("User %s registered successfully." % username)

        return jsonify(success=True, message="Registration successful!")

    except pymongo.errors.DuplicateKeyError as e:
        # Catch pymongo exception
        return jsonify(success=False, message="Duplicated username or email!"), 403

我想要三个测试:有效、无效(重复的用户名)、无效(重复的电子邮件)。

# Register helper function
def register(self, username, password, name, email):
    return self.app.post(
        "/register",
        data = json.dumps(dict(username = username, password = password, name = name, email = email)),
        content_type='application/json',
        follow_redirects = True
        )

def test_02_valid_user_registration(self):
    response = self.register('test', '12345678', 'Tester 1', 'test@mail.mail')
    self.assertEqual(response.status_code, 200)
    self.assertIn(b'Registration successful!', response.data)

def test_03_invalid_user_registration_duplicate_username(self):
    response = self.register('test', '12345678', 'Tester 2', 'test1@mail.mail')
    self.assertEqual(response.status_code, 403)
    self.assertIn(b'Duplicate username or email!', response.data)

def test_04_invalid_user_registration_duplicate_email(self):
    response = self.register('test2', '12345678', 'Tester 3', 'test@mail.mail')
    self.assertEqual(response.status_code, 403)
    self.assertIn(b'Duplicate username or email!', response.data)

正如预期的那样,我得到了 DuplicateKeyError,因为我在数据库中为这些参数设置了 Unique。

pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection: user.users index: username_1 dup key: { username: "test" }

有没有办法从 DuplicateKeyError 中获取重复项,以便我可以对重复的用户名和电子邮件进行单独的单元测试?

我知道这更像是组件/集成测试而不是单元测试,但这是我知道如何在 Python 3 中执行此操作的唯一方法。

【问题讨论】:

    标签: python python-3.x mongodb flask pymongo


    【解决方案1】:

    于是我开始挖掘 DuplicateKeyError 的实现,发现它包含codedetails

    我打印了错误的details,得到了这个:

    {
        "message": {
            "code": 11000,
            "errmsg": "E11000 duplicate key error collection: user.users index: username_1 dup key: { 
                username: \"test\" 
            }",
            "index": 0,
            "keyPattern": {
                "username": 1
            },
            "keyValue": {
                "username": "test"
            }
        },
        "success": false
    }
    

    之后很容易让这两个测试工作。

    try:
        # code
    except pymongo.errors.DuplicateKeyError as e:
        # Catch pymongo exception
        key = list(e.details.get("keyValue").keys())[0]
        value = e.details.get("keyValue").get(key)
        return jsonify(success=False, message="Duplicate %s: %s" % (key, value)), 403
    

    还有测试:

    def test_03_invalid_user_registration_duplicate_username(self):
        response = self.register("test", "12345678", "Tester 2", "test1@mail.mail")
        self.assertEqual(response.status_code, 403)
        self.assertIn(b"Duplicate username: test", response.data)
    
    def test_04_invalid_user_registration_duplicate_email(self):
        response = self.register("test", "12345678", "Tester 3", "test@mail.mail")
        self.assertEqual(response.status_code, 403)
        self.assertIn(b"Duplicate email: test@mail.mail", response.data)
    

    【讨论】:

      猜你喜欢
      • 2012-06-07
      • 1970-01-01
      • 2020-10-19
      • 2022-01-05
      • 2018-10-02
      • 2016-04-10
      • 2022-11-02
      • 2013-02-08
      • 1970-01-01
      相关资源
      最近更新 更多