如何Mock自定义requests.Session子类中的send()方法?
解决Mock requests.Session.send不生效的问题
这个问题我之前也踩过坑,核心原因是你mock的目标路径不对!
问题分析
你的MySession继承自requests.Session,在do_query里调用的self.send(),本质是调用MySession实例的send方法——这个方法是从父类Session继承来的,但当你创建MySession类时,它已经把父类的send方法绑定到自己的类属性上了。你现在mock的是requests.Session.send,这只会影响直接用Session实例调用的场景,不会影响已经继承了该方法的MySession实例。
正确的Mock方式
你需要mock的是**MySession类的send方法**,而不是父类的。具体路径取决于你的MySession定义在哪个模块:
情况1:MySession和测试类在同一个文件
修改mock装饰器的路径为当前模块的MySession.send:
@mock.patch('__main__.MySession.send') # __main__表示当前模块 def test_test(self, session_mock): session_mock.return_value = FakeResult() req = CatchData('test') s = MySession() s.do_query(req) # 可选:验证mock是否被调用,确认生效 session_mock.assert_called_once()
情况2:MySession在单独的模块(比如myapp/session.py)
如果你的MySession定义在myapp.session模块里,那么mock路径应该是:
@mock.patch('myapp.session.MySession.send') def test_test(self, session_mock): session_mock.return_value = FakeResult() req = CatchData('test') s = MySession() s.do_query(req)
原理补充
Python的mock是通过替换指定路径下的对象来生效的。当你mockMySession.send时,所有新创建的MySession实例调用self.send()都会使用mock后的方法,因为实例会先从自己的类中查找send属性,而你已经把类的send替换成了mock对象。
内容的提问来源于stack exchange,提问作者Alice Thornberry
相关产品推荐
相关产品推荐

