python - Django 单元测试 - 查询测试数据库内容
问题描述
有人可以指出我在单元测试期间如何查询 Django 测试数据库的特定表的资源吗?
我有以下测试代码:
from django.test import TestCase
from users.models import User
class DisputeAssignerTestSuite(TestCase):
databases = [
'default',
'read_replica',
]
@classmethod
def setUpTestData(cls):
cls.users = UserFactory.create_batch(50)
def test_firstOne(self):
print(users)
print(User.objects.all())
用户工厂代码:
import factory
from faker import Factory
import pytz
from users.models import User
faker = Factory.create()
class UserFactory(factory.DjangoModelFactory):
class Meta:
model = User
django_get_or_create = ('first_name', 'last_name', 'timezone', 'locale')
first_name = factory.LazyAttribute(lambda _: faker.first_name())
last_name = factory.LazyAttribute(lambda _: faker.last_name())
display_name = factory.LazyAttribute(lambda _: _.first_name + " " + _.last_name)
timezone = factory.LazyAttribute(lambda _: faker.timezone())
locale = factory.LazyAttribute(lambda _: faker.random_choices(elements=('en-au', 'en-us', 'de-de', 'fr-fr'), length=1))
password = factory.LazyAttribute(lambda _: faker.password(length=12))
last_login = factory.LazyAttribute(lambda _: faker.past_datetime(start_date="-60d", tzinfo=pytz.timezone(faker.timezone())))
is_superuser = factory.LazyAttribute(lambda _: faker.boolean(50))
email = factory.LazyAttribute(lambda _: faker.email())
username = factory.LazyAttribute(lambda _: _.email)
is_staff = factory.LazyAttribute(lambda _: faker.boolean(50))
is_active = factory.LazyAttribute(lambda _: faker.boolean(50))
date_joined = factory.LazyAttribute(lambda _: faker.past_datetime(start_date="-1y", tzinfo=pytz.timezone(faker.timezone())))
我不明白,我如何在 Django 为这个 TestCase 运行创建的测试数据库中查询用户表,例如验证它的内容是否符合某些特定要求(例如,存在特定名字的用户等)。
当我写:
print(User.objects.all())
我得到了生产数据库的输出。
帮助!
更新:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': global_config['postgresql']['database'],
'USER': global_config['postgresql']['user'],
'PASSWORD': global_config.get('postgresql', 'password'),
'HOST': global_config['postgresql']['host'],
'PORT': global_config['postgresql']['port'],
'CONN_MAX_AGE': 30,
'TEST': {
'NAME': 'mytestdatabase',
},
'OPTIONS': {
'connect_timeout': 60,
'sslmode': 'prefer'
},
},
'read_replica': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': global_config['postgresql']['database_read_replica'],
'USER': global_config['postgresql']['user_read_replica'],
'PASSWORD': global_config.get('postgresql', 'password_read_replica'),
'HOST': global_config['postgresql']['host_read_replica'],
'PORT': global_config['postgresql']['port_read_replica'],
'CONN_MAX_AGE': 30,
'TEST': {
'MIRROR': 'default',
},
'OPTIONS': {
'connect_timeout': 60,
'sslmode': 'prefer'
},
}
REPLICA_DATABASES = ['read_replica',]
DATABASE_ROUTERS = [
'multidb.PinningReplicaRouter',
]
解决方案
好吧,在解决了这个问题很多之后,我终于发现,用于数据库路由的“multidb.PinningReplicaRouter”中间件是问题的根源。在我的案例中,当在 Django 2.2.11 和 Python 3.7 上使用时,它阻止了将查询正确路由到测试数据库,而是破坏了 PROD/DEV 隔离层,写入 ??? (很难说,因为我无法回读)并从 PROD 数据库回读。
我已经解决了这个问题,在我想运行的测试套件前面包含以下装饰器:
@modify_settings(DATABASE_ROUTERS={'remove': 'multidb.PinningReplicaRouter'})
class SomeTestSuite(TestCase):
# some test logic
希望它对将来的某人有所帮助。
推荐阅读
- azure - Azure Function App 无法更新表行
- php - PHP 8 评论错误
- json - 我有一个提供一些文本数据的 api,但文本在 ListStyle 中不起作用
- node.js - 如何在没有节点的情况下运行基于 HTML 的 Web 组件?
- javascript - 如何将多个文件大小排列到单个 HTML 卡中?
- sql-server - 从 SQL Server 数据库向 FCM 推送通知
- python - Dealing with a corrupt/bugged pip installation in osx
- node.js - 如果属性具有特定值,有没有办法找到并返回它?
- python - 用户按下赞按钮时不会突出显示,也不会显示赞数 ..in django。你能建议我任何解决方案吗
- r - 卷曲错误:操作在 1000 毫秒后超时