我有一个使用其他对象的类 - 来自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)
您的代码是算法核心和与外部库的一些交互的混合。由于这种混合性质,似乎需要一些嘲弄来处理他对单元测试的交互,并且我理解你的问题,以便你想知道它是否值得麻烦。
该算法足够复杂(我会说),以证明一些测试的努力。但是,是否使用必要的模拟来测试原始代码是值得的(取决于评论中提到的)函数的关键性。
但是,在这种特殊情况下,通过简单的设计更改可以消除模拟的努力:您可以将要测试的算法与与外部库的交互分开:
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
。