我有一个使用其他对象的类 - 来自scikit-learn
的MultinomialNB。这个类有一个使用这个对象的函数,我想测试它。
测试它的正确方法是什么?我应该模拟从其他库导入的对象吗?我想这比编写这个函数需要花费更多的时间。
class MyClass:
def __init__():
self.model = MultinomialNB()
self.extr = FeatureExtractor()
... other methods
def get_most_coefficient_features(self):
if len(self.model.coef_) != len(self.model.classes_):
raise Exception("Different number of model features than coefs.")
result = dict()
for i, target in enumerate(self.model.classes_):
feats = sorted(zip(self.extr.features, self.model.coef_[i]), key=lambda t: t[1])
result[target] = feats
return result
我应该这样测试吗? (实际上我不能,因为我不能覆盖“coef_”,因为它是一个属性)
def test_get_most_coefficient_features(self):
myclass_obj = MyClass()
myclass_obj.extr.features = ["F1", "F2", "F3", "F4", "F5"]
myclass_obj.model.classes_ = ["True", "False"]
myclass_obj.model.coef_ = [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1]]
res = myclass_obj.get_most_coefficient_features()
exp_res = dict({"True": ["F1", "F2", "F3", "F4", "F5"], "False": ["F5", "F4", "F3", "F2", "F1"]})
self.assertEqual(exp_res, res)
答案 0 :(得分:0)
您的代码混合了算法核心和与外部库的某些交互。由于这种混杂的性质,似乎需要进行一些模拟来处理单元测试中的交互,我理解您的问题,以便您想知道这是否值得解决。
该算法非常复杂(我会说),足以证明一些测试工作的合理性。但是,是否值得进行必要的模拟测试原始代码(如注释中所述)取决于函数的重要性。
但是,在这种特殊情况下,可以通过简单的设计更改来消除模拟工作:您可以将要测试的算法与与外部库的交互分开:
def calc_most_coefficient_features(self, features, model_coefs, model_classes):
if len(model_coefs) != len(model_classes):
raise Exception("Different number of model features than coefs.")
result = dict()
for i, target in enumerate(model_classes):
feats = sorted(zip(features, model.coefs[i]), key=lambda t: t[1])
result[target] = feats
return result
def get_most_coefficient_features(self):
return self.calc_most_coefficient_features(
self.extr.features, self.model.coef_, self.model.classes_)
您现在可以使用单元测试来测试calc_most_coefficient_features
,并使用集成测试来测试get_most_coefficient_features
。