可测试的单例装饰器

singleton-decorator的Python项目详细描述


单例装饰器

可测试的单例装饰器允许轻松创建单例对象 只需在类定义中添加一个decorator,而且还允许轻松地编写 这些类的单元测试。

一个问题

如果使用基于decorator函数的简单单例模式 用这样的内部包装函数包装类:

def singleton(cls):
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
          instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

它可以很好地与您的类一起工作,但是它使得不可能直接访问 到没有decorator的类对象。所以不能使用 单元测试中的类名:

@singleton
class YourClass:
    def method(self):
        ...
YourClass.method(...)

此代码无法工作,因为YouClass实际上包含一个包装函数 但不是你的类对象。如果您的 测试需要对象的单独实例,因此单例模式可以 打破不同测试的隔离。

溶液

singleton decorator提供了一个简单的解决方案来避免这两种情况 问题。它为每个修饰类使用单独的包装器对象,并保存 __wrapped__属性中的类,以便您可以访问修饰的类 直接在你的单元测试中。

安装

要安装singleton decorator只需在命令行中键入:

$ pip install singleton-decorator

用法

首先导入singleton decorator:

from singleton_decorator import singleton

然后用这个decorator装饰您的类:

@singleton
class YourClass:
    ...

就这些。现在,您可以创建或获取类的现有实例。 将其称为简单的类对象:

obj = YourClass()  # creates a new instance
obj2 = YourClass()  # returns the same instance
obj3 = YourClass()  # returns the same instance
...

您还可以将args和kwargs传递到类的构造函数中:

obj = YourClass(1, "foo", bar="baz")

注意

因为singleton模式只允许从 类__init__方法将用args和 第一次打电话时夸尔格斯就过去了。所有未来电话的争论 完全忽视,不会影响现有的实例。

单元测试

在您的单元测试中单独运行修饰类的方法 不实例化对象(避免运行构造函数代码)。 使用包装器对象的__wrapped__属性:

# your_module.py
@singleton
class YourClass:
    def your_method(self):
        ...
# tests.py
class TestYourClass(TestCase):
    def test_your_method(self):
        obj = mock.MagicMock()
        YourClass.__wrapped__.your_method(obj)
        ...

此测试仅使用模拟对象运行your_method的代码 作为self参数,因此测试将在完全隔离的情况下运行 不会依赖于其他代码片段,包括构造函数 方法。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java Android使用两个后台服务错误   解压缩HTTPInputStream时,java GZIPInputStream过早关闭   javax和javax的区别是什么。网ssl。密钥库和服务器。ssl。为SpringBoot应用程序指定密钥库时的密钥库属性   java生成两个JPanel,而我只需要一个   java深度链接从play store安装应用程序时获取数据   java 安卓应用程序在退出时未正确释放蓝牙   java正确使用setCellValueFactory   java开放JdbcTemplate连接处于只读模式?   使用Spring MVC创建服务时发生java错误   JavaFX获取安装在计算机中的特定应用程序的版本   SecureRandom的安全问题:PRNG在java 1.5中不一致   windows我可以创建一个独立的。带Inno设置的Java应用程序的exe安装程序?   如何使用JavaServlet下载csv文件?   java从生成的缓冲图像中添加图像作为jasper中的数据记录?   java日期和时间解析