Поблочное тестирование с одиночными элементами

Я подготовил некоторые автоматические тесты со средой тестирования Выпуска Команды Visual Studio. Я хочу, чтобы один из тестов соединился с базой данных после нормального способа, которым это сделано в программе:

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

Но я получаю исключение в этой строке. Я предполагаю, что это происходит, потому что ConfigurationManager является одиночным элементом. Как можно работать вокруг одноэлементной проблемы с модульными тестами?


Спасибо за ответы. Все они были очень поучительны.

46
задан Pure.Krome 13 October 2016 в 03:45
поделиться

3 ответа

Вы можете использовать инъекцию зависимости конструктора. Пример:

public class SingletonDependedClass
{
    private string _ProviderName;

    public SingletonDependedClass()
        : this(ConfigurationManager.ConnectionStrings["main_db"].ProviderName)
    {
    }

    public SingletonDependedClass(string providerName)
    {
        _ProviderName = providerName;
    }
}

, который позволяет подключать строку подключения непосредственно объектом во время тестирования.

Также, если вы используете Framework Edition Team Edition Visual Studio Team, вы можете сделать конструктор с параметром частным и тестировать класс через Accessor.

На самом деле я решаю такие проблемы с издевательствами. Пример:

У вас есть класс, который зависит от Singleton:

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;
    }
}

SingletondEpendedClass ( ( используется библиотека MOQ Mocking ):

[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);
    ...
}
13
ответ дан 26 November 2019 в 20:16
поделиться

Вы сталкиваетесь с более общей проблемой здесь. При неправильном использовании синглтоны препятствуют Testabiliy.

Я сделал подробный анализ этой проблемы в контексте отделенного дизайна. Я постараюсь обобщить мои очки:

  1. Если ваш синглтон несет значительное глобальное состояние, не используйте Singleton. Это включает в себя постоянное хранение, такое как базы данных, файлы и т. Д.
  2. в случаях, когда зависимость от объекта Singleton не очевидна на имя классов, зависимость должна быть введена. Необходимость вводить экземпляры синглтона на классы доказывают неправильное использование шаблона (см. Точку 1).
  3. Предполагается, что жизненный цикл Singleton считается таким же, как приложение. Большинство реализаций Singleton используют механизм ленивого нагрузки для создания самих островов. Это тривиально, и их жизненный цикл вряд ли изменится, иначе вы не должны использовать Singleton.
5
ответ дан 26 November 2019 в 20:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: