首頁>Program>source

我已经使用Visual Studio Team Edition測試框架準備了一些自動測試.我希望其中一種測試按照程式中正常的方式連線到資料庫:

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

但是我在這一行收到一个例外.我想發生這種情况是因為ConfigurationManager是單例.您如何通過單元測試解決單例問题?


感谢您的答複.所有這些都非常有啟發性。

最新回復
  • 5月前
    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在他的博客上寫了一篇指南:編寫可測試代碼。

  • 5月前
    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
    

  • 5月前
    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) {
        ...
        }
        ...
    }
    

  • 5月前
    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'