У нас есть довольно общий объект в нашем приложении. В этом случае мы будем называть это мячом. Шарики работают нормально, но в некоторых конфигурациях они действуют по-разному. В настоящее время он настроен так:
class Ball
{
private static readonly bool BallsCanExplode;
static Ball()
{
bool.TryParse(ConfigurationManager.AppSettings["ballsCanExplode"],
out BallsCanExplode);
}
public Ball(){}
}
Это прекрасно работает на практике. Если конфигурация такова, что шары могут взорваться, они взрываются, а если нет, то нет. Проблема в том, что он абсолютно не тестируемый. Я не смог найти хороший способ сделать его тестируемым, и все же его легко было создать.
Самое простое решение - просто отделить шар и конфигурацию:
class Ball
{
private readonly bool CanExplode;
public Ball(bool canExplode);
}
Проблема в том, что то, что когда-то было изолированной зависимостью в классе Ball, теперь распространилось на каждый класс, который создает Ball. Если это вводит зависимость, то знание взрывающихся шариков должно быть введено везде.
Та же проблема существует с BallFactory. В то время как каждый класс мог просто идти new Ball()
, теперь он должен знать о BallFactory, который нужно вводить везде. Другой вариант - использовать сервисный локатор, который уже встроен в приложение:
class Ball
{
private readonly bool CanExplode;
public Ball()
{
CanExplode = ServiceLocator.Get<IConfiguration>().Get("ballsCanExplode");
}
}
Это все еще сохраняет зависимость конфигурации в шаре, но позволяет вводить тестовую конфигурацию. Однако шары используются настолько часто, что кажется излишним находить службу при каждом вызове new Ball()
.
Каков наилучший способ сохранить этот тестируемый объект так же легко, как создать экземпляр?
Примечание. В приложении есть как структура внедрения зависимостей, так и локатор служб, которые часто используются.