如何模拟 django.db.connection.schema_name

How to mock django.db.connection.schema_name

我正在尝试测试多租户 Django 应用程序。我正在尝试模拟与 public 租户的连接:

class ViewsTest(ViewTestUtilsMixin, TenantTestCase):
    def setUp(self):
        self.factory = RequestFactory()

    def test_some_public_only_view(self)
         # generate a request instance so we can call our view directly
        request = self.factory.get('/')

        with patch('tenant.views.connection.schema_name', return_value=get_public_schema_name()):
            response = some_public_only_view(request)  
            self.assertEqual(response.status_code, 200)

但是,当我在测试期间调试它以检查 some_public_only_view 方法中 schema_name 的值时,我得到了这个:

<MagicMock name='schema_name' id='140578910478880'>,

所以至少我知道我正在修补正确的位置。问题是 schema_name 不是方法,所以它不使用 return 值。

那么我如何模拟 schema_name?正在测试的视图在 tenant/views.py

中以这种方式使用它
def some_public_only_view(request):

    if connection.schema_name == get_public_schema_name():
         # do stuff
         # returns a good view, 200
    else:
         raise Http404

我也试过这个:

with patch.object('tenant.views.connection', 'schema_name', get_public_schema_name()):

这给了我:AttributeError: tenant.views.connection does not have the attribute 'schema_name'

您可以使用 PropertyMock 以这种方式模拟对象 属性:

@patch('tenant.views.connection.schema_name', new_callable=PropertyMock(return_value="abc"))
def test_some_public_only_view(self, mock_schema):
...

这里是文档https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock

总之,你的做法没有问题,其实我也测试过你的代码:

with patch.object('tenant.views.connection', 'schema_name', get_public_schema_name()):

而且我没有收到任何错误。

我在没有设置正确的数据库后端的情况下第一次尝试时遇到了这个错误 AttributeError: tenant.views.connection does not have the attribute 'schema_name',它应该来自 tenant_schemas 库,其中之一是:postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle' , 我用过 tenant_schemas.postgresql_psycopg2

如果这是原因(数据库设置配置错误),如果您尝试 运行 您的测试而不打补丁 schema_name,您应该会遇到此错误

AttributeError: 'DatabaseWrapper' object has no attribute 'schema_name'

如此处所述:https://github.com/bernardopires/django-tenant-schemas/issues/328