单元测试自定义GroupImputer时如何跳过transform的check_is_fitted校验
跳过
check_is_fitted校验的几种实现方案 方案1:直接手动绑定impute_map_属性(最推荐,无需修改源码)
check_is_fitted的核心逻辑就是校验实例是否存在传入的带尾部下划线的拟合后属性,你已经提到测试场景会预先提供impute_map_,那只要在调用transform前手动给实例绑定你构造好的impute_map_,校验会直接通过,不需要做任何额外修改,测试示例代码如下:
import pandas as pd # 构造测试所需的预定义impute_map test_impute_map = pd.DataFrame({ "group_col": ["A", "B"], "impute_col": [10, 20] }) # 实例化后无需调用fit方法 imputer = GroupImputer(group_cols=["group_col"], impute_cols=["impute_col"], metric="mean") # 手动绑定拟合属性 imputer.impute_map_ = test_impute_map # 调用transform不会触发校验异常 test_df = pd.DataFrame({"group_col": ["A", "B", "A"], "impute_col": [None, 5, None]}) result = imputer.transform(test_df)
方案2:用Mock工具打桩替换校验函数(适合无需真实impute_map_的测试场景)
如果你需要完全跳过校验逻辑,不需要判断属性是否存在,可以用单元测试框架的Mock能力临时替换check_is_fitted函数,示例如下:
pytest 用法
def test_transform(monkeypatch): # 打桩让校验函数直接返回,不做任何检查 monkeypatch.setattr("sklearn.utils.validation.check_is_fitted", lambda *args, **kwargs: None) imputer = GroupImputer(group_cols=["group_col"], impute_cols=["impute_col"], metric="mean") # 自行赋值测试所需的属性 imputer.impute_map_ = 测试用impute_map数据 test_df = pd.DataFrame({"group_col": ["A"], "impute_col": [None]}) result = imputer.transform(test_df)
unittest 用法
from unittest.mock import patch def test_transform(): with patch("sklearn.utils.validation.check_is_fitted") as mock_check: mock_check.return_value = None imputer = GroupImputer(group_cols=["group_col"], impute_cols=["impute_col"], metric="mean") imputer.impute_map_ = 测试用impute_map数据 test_df = pd.DataFrame({"group_col": ["A"], "impute_col": [None]}) result = imputer.transform(test_df)
方案3:源码增加测试开关(适合高频测试场景)
如果你需要频繁做这类测试,可以在源码中加一个默认关闭的校验开关,不影响生产环境的使用:
def __init__(self, group_cols, impute_cols, metric, skip_fit_check=False): self.group_cols = group_cols self.impute_cols = impute_cols self.metric = metric self.skip_fit_check = skip_fit_check def transform(self, df): if not self.skip_fit_check: check_is_fitted(self, 'impute_map_') # 剩余原有逻辑保持不变
测试时实例化传入skip_fit_check=True即可直接跳过校验。
内容的提问来源于stack exchange,提问作者ddd
相关产品推荐
相关产品推荐

