可测试的单例装饰器

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本机方法的源代码可用吗?   java如何使父方法抛出异常?   java Android以编程方式设置不同屏幕大小/密度的布局   java如何使用一个变量来管理所有客户端请求   java输入一个txt文件,每行有一组数字   json java从jsonobject获取jsonarray错误   java将一个(WAV)写入一个文件只会说一个单词(最后一个单词)   java Telnet忽略原始字节   proguard java。运行桌面应用程序时出现lang.VerifyError   java用左键移动JLabel?   java如何在jText区域验证选项卡?   文件服务器客户端Javasocket编程中的字符串搜索   java省略了JSTL中的最后一个逗号<c:out>   java如何找到if或else代码已执行的次数?   java JavaScript WebSocket send()方法未执行   浮点数声明上的java标识符预期错误   java这是指二进制搜索算法吗?   编译mod at:reobfJar java时的minecraft问题。util。拉链ZipException:重复条目   java检测特定的震动运动(如图所示:D)