Я подготовил некоторые автоматические тесты со средой тестирования Выпуска Команды Visual Studio. Я хочу, чтобы один из тестов соединился с базой данных после нормального способа, которым это сделано в программе:
string r_providerName = ConfigurationManager.ConnectionStrings["main_db"].ProviderName;
Но я получаю исключение в этой строке. Я предполагаю, что это происходит, потому что ConfigurationManager является одиночным элементом. Как можно работать вокруг одноэлементной проблемы с модульными тестами?
Спасибо за ответы. Все они были очень поучительны.
Посмотрите блог Google Testing:
А также:
Наконец, Мишко Хевери написал руководство в своем блоге: Пишет надпись Testable Code.
Вы можете использовать инъекцию зависимости конструктора. Пример:
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);
...
}
Вы сталкиваетесь с более общей проблемой здесь. При неправильном использовании синглтоны препятствуют Testabiliy.
Я сделал подробный анализ этой проблемы в контексте отделенного дизайна. Я постараюсь обобщить мои очки: