如何对类__init__中调用的bar方法做单元测试并跳过foo调用?
测试__init__中调用的类方法并跳过foo()的执行
要测试bar方法同时避免执行foo(),你可以借助Python的unittest.mock模块来mock掉foo方法,同时手动设置bar依赖的list属性。下面是具体的实现步骤和示例:
1. 先修正原代码的小问题
你的代码里有几个语法/逻辑小问题,先调整一下方便后续测试:
__init__方法必须以self作为第一个参数bar方法调用时传了'hello',但定义时没有参数,需要对应上list应该作为实例属性(self.list),否则方法间无法共享
修正后的类代码:
class abc: def __init__(self, path): self.list = [] self.foo(path) self.bar('hello') # 这里传参和方法定义对应 def foo(self, path): # 实际的复杂逻辑 self.list = ['实际数据'] # 示例赋值 def bar(self, msg): # 使用self.list做处理的逻辑 return f"{msg}: {self.list}"
2. 编写测试用例
我们可以用unittest.mock.patch来mock掉foo方法,让它在初始化时不执行实际逻辑,然后手动给实例的self.list设置测试用的模拟数据,最后测试bar的行为。
用unittest框架的示例:
import unittest from unittest.mock import patch from your_module import abc # 替换成你的类所在的模块名 class TestAbcBar(unittest.TestCase): @patch('your_module.abc.foo') # mock类的foo方法 def test_bar_method(self, mock_foo): # 1. 创建实例,此时foo会被mock,不会执行实际逻辑 test_path = '/test/path' instance = abc(test_path) # 2. 验证foo确实被调用了(可选,根据你的测试需求) mock_foo.assert_called_once_with(test_path) # 3. 设置mock的list属性,替换掉初始化时的空列表 instance.list = ['测试数据1', '测试数据2'] # 4. 调用bar方法并断言结果 result = instance.bar('test') self.assertEqual(result, 'test: [\'测试数据1\', \'测试数据2\']') if __name__ == '__main__': unittest.main()
用pytest框架的示例:
如果你用pytest,写法会更简洁:
from unittest.mock import patch from your_module import abc def test_bar_method(): with patch('your_module.abc.foo') as mock_foo: # 创建实例 instance = abc('/test/path') # 设置mock的list instance.list = ['测试数据'] # 测试bar assert instance.bar('hello') == 'hello: [\'测试数据\']' # 可选:验证foo被调用 mock_foo.assert_called_once_with('/test/path')
关键思路解释
- mock foo方法:通过
patch装饰器/上下文管理器,我们替换了类中的foo方法,让它变成一个mock对象,初始化时调用的是这个mock,不会执行原方法的复杂逻辑。 - 手动设置实例属性:因为
bar依赖self.list,我们直接给实例的list属性赋值测试数据,模拟foo方法原本会做的初始化工作。 - 验证调用(可选):如果需要确认
foo在初始化时确实被调用了,可以用mock_foo.assert_called_once_with(...)来做断言。
这样就能单独测试bar方法的逻辑,完全不受foo方法的影响啦!
内容的提问来源于stack exchange,提问作者tsar2512
相关产品推荐
相关产品推荐

