简体   繁体   English

如何为具有多个状态的Singleton对象运行测试用例?

[英]How to run test cases for Singleton object with multiple state?

I have a singleton object in C#. 我在C#中有一个单例对象。

This singleton object works based on some state assigned to it. 该单例对象根据分配给它的某些状态工作。

I dont have any method to switch state of singleton object at run time. 我没有任何方法在运行时切换单例对象的状态。 Also I dont need it as application always start in one state and remains in same state. 我也不需要它,因为应用程序始终以一种状态启动并保持相同状态。

Problem is while writing the test cases. 问题在于编写测试用例时。 I have written the test cases for each state. 我已经为每种状态编写了测试用例。 But I cant run it because the for all test cases I have single object with one state. 但是我无法运行它,因为对于所有测试用例,我都具有一个状态的单个对象。

How to run the tests for other state. 如何针对其他状态运行测试。 How to re-create the object for each test? 如何为每个测试重新创建对象?

I dont want to change the singleton object code for test cases. 我不想更改测试用例的单例对象代码。

Any thought or idea will be much appreciated. 任何想法或想法将不胜感激。

This is one of the reasons why it is handy not to manage the lifetime of a class yourself, but to have an Inversion of Control (IoC) container such as Autofac or Unity do it for you. 这就是为什么不方便自己管理类的生存期,而是让诸如AutofacUnity这样的控制反转(IoC)容器为您做到这一点的原因之一。 You then simply create a class, that looks like any other class, and tell your IoC container to instantiate it as a singleton. 然后,您只需创建一个类似于其他任何类的类,并告诉您的IoC容器将其作为单例实例化。

See also An Autofac Lifetime Primer . 另请参见Autofac生命周期入门

In the case when you cannot use an IoC container (can't think of any, but let's be flexible), you can create an internal class that contains your "singleton"'s logic -- and this internal class is just that, an internal class, not a singleton... 在无法使用IoC容器的情况下(想不出什么,但是要灵活一点),您可以创建一个包含“单例”逻辑的internal类,而这个内部类就是这样,内部类,不是单身...

internal class MyLogic
{
   ...
}

And then you wrap it in a public class, and make that a singleton. 然后,将其包装在一个公共类中,并使其成为单例。 If you put both these classes together in a single Project, then the internal class (the implementation of your business logic) is not accessible to your application, only the public singleton version is accessible. 如果将这两个类都放在一个项目中,则内部类(业务逻辑的实现)将无法被应用程序访问,只能访问公共单例版本。

public sealed class MySingleton 
{
    private MySingleton() { Implementation = new MyLogic(); }

    public static MySingleton Instance { ... }

    private MyLogic Implementation { get; set; }

    ...
}

But then you can point out in your AssemblyInfo that your unit-test project does have access to the internal class by using 但是,然后您可以在AssemblyInfo指出,通过使用以下命令,您的单元测试项目确实可以访问内部类

[assembly: InternalsVisibleTo("MySolution.UnitTests")]

This way, you can unit test your logic class while your application(s) can only use it as a Singleton. 这样,您可以对逻辑类进行单元测试,而您的应用程序只能将其用作Singleton。

Frankly I prefer the IoC way but if that's new to you, it's probably faster to implement the above solution instead. 坦率地说,我更喜欢使用IoC方式,但是如果您不熟悉IoC方式,则可以更快地实施上述解决方案。

Good luck! 祝好运!

I dont want to change the singleton object code for test cases. 我不想更改测试用例的单例对象代码。

Maybe it's the time to think about changing it for your whole program. 也许是时候考虑为整个程序进行更改了。 Is there a reason you need this to be singleton? 是否有你需要这是单身的一个原因? Singleton is a great pattern if you need it , but it's often misused by people who want to use global variables but have heard that they are evil. 如果您需要 ,Singleton是一个很好的模式,但是它经常被想要使用全局变量但听说过它们是邪恶的人滥用。 Now they program singletons, because they work the same while being one of those "patterns" that are cool OOP. 现在,他们对单例进行编程,因为它们是很酷的OOP的“模式”之一,它们的工作原理相同。

But a singleton is nothing but a global. 但是单身人士不过是一个整体。 And it has the same problems as a global. 它具有与全球相同的问题。 If you use that pattern, make sure you actually need it, because it comes with problems attached and you need to weight the benefits against the drawbacks. 如果使用该模式,请确保确实需要它,因为它附带有问题,因此需要权衡利弊。 If you don't use the benefits, you only have drawbacks. 如果您不使用收益,那么您只会有弊端。

我建议您在可能的情况下避免单例,请参阅Misko Hevery的演讲: Clean Code Talks

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM