Java中“不建议使用Static函数“的原则在Python中的改变

Java中“不建议使用Static函数“的原则在Python中的改变,第1张

Java中“不建议使用Static函数“的原则在Python中的改变

文章目录

背景:为什么Java中不建议使用Static函数实验:Python是否可以Mock Static?

方法模块方法 结论:Python中需要注意的问题

背景:为什么Java中不建议使用Static函数

这个问题要从测试驱动开发说起。在进行设计前,先考虑如何测试。当模块存在依赖关系,我们通常使用Mock的方式模拟被依赖对象来分离关注点。而在反射技术和Mockito等工具尚未像现在这样成熟之前,测试人员需要手动编写模拟类,这个手动编写的类需要和真实类继承自相同的接口。为了让被依赖的对象是可替换的,这就要求:

对象间不存在直接的的依赖关系,而是依赖于共同的抽象接口——高层对象调用低层对象的接口,低层对象实现该接口,使用依赖注入的方式注入被依赖对象。

在Java中,Staic函数难以被替换,因此依赖于Static函数的模块是难以测试的,故留下了这样的传统。

实验:Python是否可以Mock Static?

在Python中,类,甚至模块也是对象,那么使用现有的Pytest-Mock是否可以Mock 一个Static函数呢?下面用一个实验来说明类方法和模块方法两种情况:

类方法
# CM.py
class C:
    
    @staticmethod
    def s():
        return 0
    
# tests/test_CM.py
from pytest_mock import MockerFixture

from CM import C,m
import CM

def test_no_mock():
    assert C.s() == 0
    
def test_mock(mocker:MockerFixture):
    mocker.patch.object(C,'s',return_value=1)
    assert C.s() == 1

可以看出,类的方法被正确Mock了

模块方法
# CM.py
def m():
    return 0
# test_CM.py
def test_mockm(mocker:MockerFixture):
    assert m()==0
    mocker.patch.object(CM,"m",return_value=1)
    assert m()==0  # 注意,这里是0,而不是1 
    assert CM.m()==1

可以看出,在使用模块调用方法时可以被正确Mock,但直接调用的方法的方法的情况下没有正确Mock。

结论:Python中需要注意的问题

从上面实验可以看出,在Pytest-mock中,

可以Mock类的static方法,无需顾忌这条规则;也可以Mock模块的方法,但直接调用则无效。需要使用module_name.method_name的方法调用。

因此,python编码建议:对于模块方法,不要直接使用from 模块 import 方法 方法名()来调用,而是import 模块 模块名.方法名()的方式调用。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5719494.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存