我试图通过模拟大多数测试的密码哈希来加快我的 Flask 应用程序的测试速度。我在 Windows 上使用 pytest 和 Python 3.8。
我尝试过以下方法:
import pytest
import werkzeug.security
@pytest.fixture(autouse=True)
def mock_password_hash(monkeypatch, request):
if "no_mock_password_hash" in request.keywords:
pass
else:
def mock_hash(*args, **kwargs):
return "123456"
monkeypatch.setattr(werkzeug.security, 'generate_password_hash', mock_hash)
和
import pytest
import werkzeug.security
from unittest import mock
@pytest.fixture(autouse=True)
def mock_password_hash(request):
"""
Mocks the built in method hashlib.pbkdf2 to decrease test runtime.
"""
if "no_mock_password_hash" in request.keywords:
yield None
else:
with mock.patch.object(
werkzeug.security, 'generate_password_hash', return_value="123456"
) as _mocked_hash:
yield _mocked_hash
我已经使用此测试测试了上述两种装置:
def test_hash_autouse():
g = Guest(0, 'username', 'password', 'name', 'email')
assert g.password == '123456'
并且两次都失败且没有错误:
def test_hash_autouse():
g = Guest(0, 'username', 'password', 'name', 'email')
> assert g.password == '123456'
E AssertionError: assert 'pbkdf2:sha25...b4faf022af81c' == '123456'
E - pbkdf2:sha256:150000$M1zININg$559128a3793e155eb472d1c1e7f686b7c8cb802a296d6a8b38ab4faf022af81c
E + 123456
还有我的客座模特:
from dataclasses import dataclass
from flask_login import UserMixin
from flask_pymongo import ObjectId
from werkzeug.security import check_password_hash, generate_password_hash
@dataclass
class Guest(UserMixin):
_id: ObjectId
username: str
_password: str
name: str
email: str
def __post_init__(self):
# Sets password hash on user registration
# When class is reinstantiated from DB password is not re-hashed
if "pbkdf2:sha256:" not in self._password:
self._password = generate_password_hash(self._password)
@property
def password(self):
return self._password
@password.setter
def password(self, val):
self._password = generate_password_hash(val)
@property
def id(self):
return self._id
@id.setter
def id(self, val):
self._id = val
def check_password(self, password):
return check_password_hash(self._password, password)
有什么想法吗?谢谢。
最佳答案
由于 monkeypatch.setattr
的工作方式与 unittest.mock.patch.object
类似,因此 advice applies
由此而来:
[monkeypatch.setattr] works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test.
在这种情况下,from
导入引入了一个新名称,指向您尝试修补的对象,因此您需要确保在该模块中修补它
您有两种选择来解决此问题,要么在应用程序中使用 import werkzeug.security
并保持测试代码相同,要么调整补丁以将功能修补到模型模块之外
请注意,from
导入基本上等同于:
- 使模块在
sys.modules
中全局可用 - 为
from module_name import imported_name [as asname] 分配
asname = getattr(sys.modules[module_name], imported_name)
关于python - 用于测试的模拟密码哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58864006/