首页>Program>source

我已经使用Visual Studio Team Edition测试框架准备了一些自动测试.我希望其中一种测试按照程序中正常的方式连接到数据库:

string r_providerName = ConfigurationManager.ConnectionStrings["main_db"].ProviderName;

但是我在这一行收到一个例外.我想发生这种情况是因为ConfigurationManager是单例.您如何通过单元测试解决单例问题?


感谢您的答复.所有这些都非常有启发性。

最新回答
  • 2021-1-10
    1 #

    看看Google Testing博客:

      Using dependency injection to avoid singletons

      Singletons are Pathological Liars

      Root Cause of Singletons

      Where have all the Singletons Gone?

      Clean Code Talks - Global State and Singletons

      Dependency Injection.

    还有:

      Once Is Not Enough

      Performant Singletons

    最后,Misko Hevery在他的博客上写了一篇指南:编写可测试代码。

  • 2021-1-10
    2 #

    您可以使用构造函数依赖注入.示例:

    public class SingletonDependedClass
    {
        private string _ProviderName;
        public SingletonDependedClass()
            : this(ConfigurationManager.ConnectionStrings["main_db"].ProviderName)
        {
        }
        public SingletonDependedClass(string providerName)
        {
            _ProviderName = providerName;
        }
    }
    

    这使您可以在测试期间将连接字符串直接传递给对象。

    此外,如果您使用Visual Studio Team Edition测试框架,则可以将带有参数的构造函数设为私有,并通过访问器测试该类。

    实际上,我通过模拟解决了这类问题.示例:

    您有一个依赖于单例的Class程:

    public class Singleton
    {
        public virtual string SomeProperty { get; set; }
        private static Singleton _Instance;
        public static Singleton Insatnce
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new Singleton();
                }
                return _Instance;
            }
        }
        protected Singleton()
        {
        }
    }
    public class SingletonDependedClass
    {
        public void SomeMethod()
        {
            ...
            string str = Singleton.Insatnce.SomeProperty;
            ...
        }
    }
    

    首先 SingletonDependedClass 需要重构以采取 Singleton 实例作为构造函数参数:

    public class SingletonDependedClass
    {    
        private Singleton _SingletonInstance;
        public SingletonDependedClass()
            : this(Singleton.Insatnce)
        {
        }
        private SingletonDependedClass(Singleton singletonInstance)
        {
            _SingletonInstance = singletonInstance;
        }
        public void SomeMethod()
        {
            string str = _SingletonInstance.SomeProperty;
        }
    }
    

    威兹维兹测试 (使用Moq模拟库):

    SingletonDependedClass
    

  • 2021-1-10
    3 #

    [TestMethod()] public void SomeMethodTest() { var singletonMock = new Mock<Singleton>(); singletonMock.Setup(s => s.SomeProperty).Returns("some test data"); var target = new SingletonDependedClass_Accessor(singletonMock.Object); ... } :有效使用旧版代码

    这里也给出了相同的答案: https://stackoverflow.com/a/28613595/929902

    要在测试工具中运行包含单例的代码,我们必须放宽singleton属性.这是我们的方法.第一步是向单例类添加新的静态方法.该方法允许我们替换单例中的静态实例.我们称它为 Example from Book .

    setTestingInstance
    

    现在有了该设置器,我们可以创建一个测试实例 并设置PermitRepository.我们想在测试设置中编写如下代码:

    public class PermitRepository
    {
        private static PermitRepository instance = null;
        private PermitRepository() {}
        public static void setTestingInstance(PermitRepository newInstance)
        {
            instance = newInstance;
        }
        public static PermitRepository getInstance()
        {
            if (instance == null) {
                instance = new PermitRepository();
            }
            return instance;
        }
        public Permit findAssociatedPermit(PermitNotice notice) {
        ...
        }
        ...
    }
    

  • 2021-1-10
    4 #

    您在这里面临一个更普遍的问题.如果滥用,则Singletons会妨碍获得证明.

    我已经在分离设计的背景下对此问题进行了详细的分析.我将尝试总结我的观点:

    如果您的Singleton具有重要的全局状态,请不要使用Singleton.这包括持久性存储,例如数据库,文件等。

    如果类名称对单例对象的依赖性不明显,则应注入依赖性.将Singleton实例注入类的需求证明了该模式的错误用法(请参见第1点).

    假设Singleton的生命周期与应用程序的生命周期相同.大多数Singleton实现都使用延迟加载机制实例化自己.这是微不足道的,它们的生命周期不太可能改变,否则您不应该使用Singleton。

    public void setUp() { PermitRepository repository = PermitRepository.getInstance(); ... // add permits to the repository here ... PermitRepository.setTestingInstance(repository); }

  • objective c:确定iPhone是否以编程方式被越狱
  • 使用Graph API的Facebook'FriendsgetAppUsers'