pytest-mock中被mock方法的return_value未生效问题排查
问题根因
第二种mock写法不生效的核心原因是mock对象的层级搞错了:
mocker.patch("tdd.get_image.ImageReader")返回的mock_image_reader是ImageReader类本身的mock对象,不是代码中实例化后的对象。- 业务代码执行
image_reader = ImageReader(str(file_name))时,实际拿到的实例是mock_image_reader.return_value这个自动生成的mock对象,后续调用image_reader.getSize()是在这个实例对象上调用方法。 - 你直接给类级别的mock对象设置
getSize.return_value,并没有给实际被调用的实例mock对象设置方法返回值,getSize()默认返回空的mock对象,解包时自然拿不到2个值,触发报错。
第一种写法能正常运行,是因为你patch类的时候直接把return_value指定成了自定义的、带正确getSize实现的类实例,实例调用方法时自然能拿到预期返回值。
修正方案
只需要把设置getSize返回值的对象,从类mock改成类mock对应的实例mock即可,也就是给mock_image_reader.return_value的getSize方法设置返回值:
def test_get_image_x2(mocker): """Test half size image.""" mock_image_reader = mocker.patch("tdd.get_image.ImageReader") # 修正:给实例化后的mock对象设置getSize返回值 mock_image_reader.return_value.getSize.return_value = (1, 1) mocker.patch("tdd.get_image.Image") get_std_aspect_image(Path("tests/python-logo.png"), size="x 0.5") tdd.get_image.Image.assert_called_once_with( "tests/python-logo.png", width=0.5, height=0.5 )
改完之后运行用例就能正常通过,这种写法比自定义Mock类的写法更简洁,也符合pytest-mock的常规使用习惯。
内容的提问来源于stack exchange,提问作者agossino
相关产品推荐
相关产品推荐

