如何使用 DUnit 测试 Singleton 类?
或者使用另一种设计模式更好?
Or it's better to use another Design Pattern?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
或者使用另一种设计模式更好?
Or it's better to use another Design Pattern?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
几天前回复了类似的问题这里,嘲笑单例< /a>.原始帖子适用于 C#.Net 关于模拟单例行为的内容,但仍应适用。
至于单例模式,它本身并没有什么问题——在很多情况下我们希望集中逻辑和数据。然而,单例和静态类之间有很大的区别。将您的单例构建为静态类硬编码,以实现应用程序中的每个使用者 - 这使得单元测试非常困难!
您想要做的是为您的单例定义一个接口,公开供您的消费者使用的方法。反过来,无论是谁实例化您的消费者,都会传递对实现类的引用[通常这是您的应用程序,或者如果您熟悉依赖注入\控制反转,则为容器]。
无论谁实例化消费者,这个框架都负责确保只有一个实例在浮动。从静态类到接口引用的飞跃实际上并不是那么伟大[如上面的链接所示],你只是失去了全局可访问实例的便利 - 我知道我知道,全局引用非常诱人,但卢克转过身去黑暗面,你也可以!
一般来说,最佳实践建议避免静态引用,并鼓励针对接口进行编程。请记住,仍然可以在这些约束下应用单例模式。遵循这些准则,您应该可以毫无问题地对您的工作进行单元测试:)
希望这会有所帮助!
singleton != public static class,而不是singleton == single instance
Responded to a similar question some days ago here, mocking a Singleton. The original post is for C#.Net as regards mocking a singleton's behaviour, but should still apply.
As regards the singleton pattern, there isn't anything wrong with it per se - in many cases we want to centralize logic and data. However, there is a very big difference between a singleton and a static class. Building your singleton as a static class hard codes that implementation to every consumer in your application - which makes unit testing very difficult!
What you want to do is define an interface for your singleton, exposing the methods for your consumers to use. Your consumers in turn are passed a reference to an implementing class by whomever instantiates them [typically this is your application, or a container if you are familiar with Dependency Injection\Inversion of Control].
It's this framework, whomever is instantiating the consumers, that is responsible for ensuring one and only one instance is floating around. It's really not that great a leap from static class to interface reference [as demonstrated in link above], you just lose the convenience of a globally accessible instance - i know i know, global references are terribly seductive, but Luke turned his back to the Dark Side, so can you!
Generally speaking, best practices suggest avoiding static references, and encourages progamming against interfaces. Remember, it is still possible to apply the singleton pattern with these constraints. Follow these guidelines, and you should have no problem unit testing your work :)
Hope this helps!
singleton != public static class, rather singleton == single instance
缺乏可测试性是经典单例模型(返回实例的静态类方法)的主要缺点之一。就我而言,这足以重新设计任何使用单例的代码以使用其他设计。
如果您绝对需要有一个单一实例,那么依赖注入和写入接口(如 johnny g 所建议的那样)绝对是最佳选择。
Lack of testability is one of the major downfalls of the classic Singleton model (static class method returning an instance). As far as I'm concerned, that's justification enough to re-design any code that uses Singletons to use some other design.
If you absolutely need to have a singular instance, then Dependency Injection and writing to an interface, as suggested by johnny g, is definitely the way to go.
我正在使用以下模式当我编写一个可以模拟的基于静态的单例时。代码是Java的,但我想你会明白的。这种方法的主要问题是您必须将构造函数放松为受包保护(这有点击败了真正的单例)。
作为旁注 - 该代码适用于模拟“静态”代码的能力,而不必简单地调用它
I'm using the following pattern when I write a static-based singletons that I can mock. The code is Java, but I think you will get an idea. The main problem with this approach is that you have to relax constructor to package-protected (which sorta defeats a true singleton).
As a side note - the code applies to ability to mock your "static" code not necessarily simply calling it
我通常只对享元对象或类似的值对象使用单例。研究 IoC 容器(如上所述)可能是比单例更好的处理共享对象的方法。
考虑一下在 Smalltalk(许多这些模式起源于此)中,true 和 false 都是有效的单例:)
I generally only use Singletons for Flyweight objects or similar value objects. Looking into an IoC container (as discussed above) is probably a better way to handle a shared object than a singleton.
Consider that in Smalltalk (where a lot of these patterns originated), true and false were both effectively singletons :)
如果你必须使用单例(并且有理由这样做......但如果可能的话我总是会尽量避免它)。我建议使用 IOC 容器来管理它。我不确定 Delphi 是否有一个。但在 Java 中你可以使用 Spring,在 .NET 中你可以使用 Windsor/Castle。 IOC 容器可以保留单例并可以注册不同的实现以进行测试。
这个主题可能太大了,无法超出这个片段。
If you must use a singleton (and there are reasons to do so...but I would always try to avoid it if possible). I would recommend using a IOC container to manage it. Im not sure if there is one for Delphi or not. But in Java you could use Spring, in .NET you can use Windsor/Castle. A IOC container can hold onto the Singleton and can register different implementations for testing.
It's probably too big of a subject to get into here beyond this snippet.