Python测试Mock BigQuery表Schema失败,返回MagicMock对象求排查
问题描述
我有一个用于获取BigQuery表Schema的简单Python函数:
# Get columns from BigQuery table def get_schema_for_table(bq_client, source, schema, table): bq_table = bq_client.get_table(f'{source}.{schema}.{table}') return bq_table.schema
为避免使用真实表,我希望在测试中创建Mock Schema和Mock Client,当前测试代码如下:
def test_get_schema_for_table(mocker): mock_client = mocker.patch('google.cloud.bigquery.Client', autospec=True) Table.schema = MagicMock(return_value=[ SchemaField('column_1', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_2', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_3', 'STRING', 'NULLABLE', None, (), None) ]) source = 'project' schema_name = 'dataset' table_name = 'existing_table' expected_schema = [SchemaField('column_1', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_2', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_3', 'STRING', 'NULLABLE', None, (), None)] returned_schema = get_schema_for_table(mock_client,source,schema_name,table_name) print(returned_schema) assert returned_schema == expected_schema
但打印returned_schema时得到的是:<MagicMock name='Client.get_table().schema' id='4591155568'>,请问我哪里出错了?
问题原因与修正
你的问题在于没有正确Mock get_table()方法的返回值,直接给Table.schema赋值并不会关联到mock client调用get_table()后返回的对象上。
修正后的测试代码:
from unittest.mock import MagicMock from google.cloud.bigquery import SchemaField def test_get_schema_for_table(mocker): # 获取模拟的Client实例 mock_client = mocker.patch('google.cloud.bigquery.Client', autospec=True).return_value # 创建模拟的Table对象并设置预设的schema mock_table = MagicMock() mock_table.schema = [ SchemaField('column_1', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_2', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_3', 'STRING', 'NULLABLE', None, (), None) ] # 指定get_table方法返回这个模拟Table mock_client.get_table.return_value = mock_table source = 'project' schema_name = 'dataset' table_name = 'existing_table' expected_schema = [ SchemaField('column_1', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_2', 'STRING', 'NULLABLE', None, (), None), SchemaField('column_3', 'STRING', 'NULLABLE', None, (), None) ] returned_schema = get_schema_for_table(mock_client, source, schema_name, table_name) assert returned_schema == expected_schema
核心说明:
- 原代码中
mock_client = mocker.patch(...)得到的是Mock类,而非实例,必须加上.return_value才能拿到可调用的客户端实例。 - 必须让
get_table()返回带有预设schema属性的模拟对象,这样函数调用bq_client.get_table()时,才能获取到你定义的schema列表,而非默认的MagicMock占位对象。
内容的提问来源于stack exchange,提问作者nimgwfc
相关产品推荐
相关产品推荐

