如何用Pytest Mock Tableau类中嵌套的self.tableau_server.views属性
正确Mock方案:绕过TSC认证+自定义views返回值
1. 先明确前提
假设你的自定义Tableau类结构大致如下(方便对应Mock逻辑):
import tableauserverclient as TSC class Tableau: def __init__(self, server_url, token_name, token_value, site_id): self.tableau_server = TSC.Server(server_url) self.tableau_server.auth.sign_in_with_personal_access_token(token_name, token_value, site_id) def get_all_views(self): all_views = [] for view in self.tableau_server.views.get(): all_views.append(view.name) return all_views
2. 核心测试代码实现
import pytest from unittest.mock import patch, MagicMock from your_module import Tableau # 替换为你的Tableau类所在模块 def test_get_all_views(): # Mock TSC.Server类,避免真实初始化和网络请求 with patch('your_module.TSC.Server') as mock_server: # 构造Server实例的Mock对象 mock_server_instance = MagicMock() # 绕过认证流程:让sign_in方法无实际操作 mock_server_instance.auth.sign_in_with_personal_access_token = MagicMock() # 构造模拟的视图对象,匹配TSC.View的属性结构 mock_view1 = MagicMock() mock_view1.name = "Sales Dashboard View" mock_view2 = MagicMock() mock_view2.name = "Customer Summary View" # 让views.get()返回自定义的可迭代视图列表 mock_server_instance.views.get.return_value = [mock_view1, mock_view2] # 让Mock的Server类返回我们构造的实例 mock_server.return_value = mock_server_instance # 初始化Tableau类(此时不会触发真实TSC认证) tableau = Tableau("dummy_url", "dummy_token", "dummy_value", "dummy_site") # 调用方法并断言结果符合预期 result = tableau.get_all_views() assert result == ["Sales Dashboard View", "Customer Summary View"] # 可选:验证认证方法是否按预期被调用 mock_server_instance.auth.sign_in_with_personal_access_token.assert_called_once_with( "dummy_token", "dummy_value", "dummy_site" )
3. 常见错误排查
- 模块未找到:检查
patch的路径是否正确。如果你的Tableau类中是import tableauserverclient as TSC,则patch路径为your_module.TSC.Server;如果是from tableauserverclient import Server,则路径改为your_module.Server。 - 构造函数属性错误:确保Mock的
Server实例包含构造函数中用到的所有子属性(如auth、views),MagicMock会自动生成这些子属性,避免"AttributeError"。 - views.get()不可迭代:确保
return_value是可迭代对象(列表、生成器等),和真实TSC返回的结构一致。
4. 简化写法(可选)
如果不需要验证认证细节,可以用链式Mock简化代码:
def test_get_all_views_simplified(): with patch('your_module.TSC.Server') as mock_server: # 链式构造Mock结构,直接指定返回值 mock_server.return_value.views.get.return_value = [ MagicMock(name="View1"), MagicMock(name="View2") ] # 绕过认证 mock_server.return_value.auth.sign_in_with_personal_access_token = MagicMock() tableau = Tableau("dummy", "dummy", "dummy", "dummy") assert tableau.get_all_views() == ["View1", "View2"]
内容的提问来源于stack exchange,提问作者Michael K
相关产品推荐
相关产品推荐

