python mock 修补顶层包

4 投票
1 回答
2009 浏览
提问于 2025-04-18 00:36

在Python中使用mock时,像argparse这样的顶级包不能直接进行修改,可能是因为没有找到可以修改的地方。一个解决办法是对包中的每一个调用进行单独修改,比如argparse.ArgumentParser。理论上,如果在没有相应修改的情况下调用了这个包,就可能在单元测试中意外触发一个导入。

虽然这种变通方法并不是特别麻烦,但如果能直接修改像argparse这样的包就更理想了。mock_open似乎使用了一些小技巧来通过__main__.open来修改内置的open()函数。这是怎么做到的呢?是否可以用类似的技巧来修改顶级包呢?

1 个回答

4
import unittest.mock as mock

mock_argparse = mock.Mock()
with mock.patch.dict('sys.modules', argparse=mock_argparse):
    import argparse
    print(argparse.ArgumentParser()) 
# <Mock name='mock.ArgumentParser()' id='140681471282448'>

关于 mock_open 的补丁:

m = mock_open()
with patch('__main__.open', m, create=True):

看起来它会创建一个 __main__.open 属性,并用一个模拟对象替代,这样就会遮盖掉内置的版本,就好像你在自己的模块里定义了 open() 函数一样。我想在实际测试中,你应该补丁 module_x.open(),其中 "module_x" 是实际调用 open() 的模块。

撰写回答