我使用工厂男孩生成一个假用户。我需要一个应该散列的字段password (在db中,这是唯一与密码相关的行)和一个clear_password值,以便知道哈希密码的相关清除密码是什么,以便以后在测试中使用。
我尝试了两种类似的方法,Params和exclude。只有排除工作,以生成一个明确的密码后哈希。问题是:在对象生成之后,我无法访问clear_password。
requirements.txt
passlib[bcrypt]
SQLAlchemy
factory-boy最小可复制示例(python 3.10使用需求的最后版本)
import random
import factory
import passlib.context
import sqlalchemy as sa
from sqlalchemy import orm
engine = sa.create_engine(
'sqlite:///test.db',
echo=True,
)
Base = orm.declarative_base(bind=engine)
pwd_context = passlib.context.CryptContext(schemes=['bcrypt'], deprecated='auto')
BCRYPT_MAX_LENGTH = 72
class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
password = sa.Column(sa.LargeBinary(BCRYPT_MAX_LENGTH), nullable=False)
...
class UserFact(factory.Factory):
class Meta:
model = User
exclude = ('clear_password',)
clear_password = factory.Faker('password', length=random.randint(8, 64))
password = factory.LazyAttribute(lambda o: bytes(
pwd_context.hash(o.clear_password), encoding='utf-8'))
...
if __name__ == '__main__':
print(UserFact().clear_password)回溯
Traceback (most recent call last):
File "path/to/file.py", line 38, in <module>
print(User().clear_password)
AttributeError: 'User' object has no attribute 'clear_password'发布于 2022-08-15 16:38:31
我知道这可能不是你想要的答案,但是,如何分配一个固定的(即。对clear_password的可预测)值?
从您的问题来看,您似乎不想测试passlib实现,因此在测试期间生成的所有User都有相同的密码应该是可以的。
对于最初的问题,您不能访问被排除的成员,因为在生成时,工厂返回它们的底层模型,而不是工厂本身。但是,您可以对返回的模型进行猴子补丁,如下所示:
# rest of code omitted
class UserFact(Factory):
class Meta:
model = User
exclude = ('clear_password',)
clear_password = Faker('password', length=random.randint(8, 64))
password = LazyAttribute(lambda o: bytes(
pwd_context.hash(o.clear_password), encoding='utf-8'))
@classmethod
def _generate(cls, create, kwargs):
# Forcing the evaluation of the provider outside of the
# _generate call in order to store the value and pass it as a kwarg
clear_password = kwargs.get("clear_password", cls.clear_password.evaluate(None, None, {"locale": "fr"}))
user = super()._generate(create, {**kwargs, "clear_password": clear_password})
# Monkey-patching the generated model
user._clear_password = clear_password
return user
if __name__ == '__main__':
# no password
print("uf = UserFact()")
uf = UserFact()
print(f'uf._clear_password : {uf._clear_password}')
print(f"Verified : {pwd_context.verify(uf._clear_password, uf.password)}")
# clear_password in kwargs
print('uf = UserFact(clear_password="test")')
uf = UserFact(clear_password="test")
print(f'uf._clear_password : {uf._clear_password}')
print(f"Verified : {pwd_context.verify(uf._clear_password, uf.password)}")https://stackoverflow.com/questions/73355266
复制相似问题