Я как бы ненавижу ответы, которые говорят «не делай этого», потому что в ответе может быть ценность, независимо от подхода, однако здесь мы идем:
Не делай этого.
Предположим, у вас есть этот класс:
public class MyCode
{
public void Do()
{
HttpContext.Current.Trace.WriteLine("WOO!");
}
}
Такие вещи не очень проверяемы.Если вы хотите провести рефакторинг для тестируемости, вы можете использовать метод типа «инверсия управления».Здесь я буду использовать «внедрение зависимостей» (есть и другие варианты, такие как «расположение службы» и «абстрактные фабрики», но это легче понять):
public class MyCode
{
private IMyLogger _logger = null;
public MyCode(IMyLogger logger)
{
_logger = logger;
}
public void Do()
{
_logger.TraceWriteLine("WOO!");
}
}
Теперь вы можете видеть, что этот кодочень тестируем, и вам не нужно перепрыгивать через обручи, чтобы что-то высмеивать.
//Confirms "Do" method calls "TraceWriteLine"
public void Do_Called_CallsTraceWriteLine()
{
//Arrange
var loggerMock = new Mock<IMyLogger>();
loggerMock.Setup(l => l.TraceWriteLine(It.IsAny<string.());
var target = new MyCode(loggerMock.Object);
//Act
target.Do();
//Assert
loggerMock.VerifyAll();
}
Теперь ваша реализация IMyLogger может вызывать HttpContext, но она поддерживает ваш целевой класс тестируемым.
public DefaultLogger : IMyLogger
{
public void TraceWriteLine(string message)
{
HttpContext.Current.Trace.WriteLine(message);
}
}
Чтобы реализовать такую вещь, многие люди предпочитают использовать Inversion of Control контейнер .Вам не нужно этого делать, но это делает вещи немного проще и не снижает удобство обслуживания, поскольку вы добавляете больше зависимостей.Вы можете вообразить, что если бы у вас был интерфейс для каждой части .NET Framework, который был непроверенным, ваши вызовы конструктора «new MyCode» начали бы становиться довольно длинными.Контейнеры IoC помогут вам избежать этого.
Популярные контейнеры IoC для .NET:
- Ninject
- Unity
- MEF (встроенный в .NET 4.0)
- Autofac
- Castle Windsor
- StructureMap
Ваш пост помечен как "ASP.NET".Надеюсь, вы используете MVC.Если это так, он имеет новую поддержку для внедрения зависимостей, примеры здесь: http://weblogs.asp.net/shijuvarghese/archive/2011/01/21/dependency-injection-in-asp-net-mvc-3-using-dependencyresolver-and-controlleractivator.aspx
Надеюсь, это поможет.Извините, это не дает прямого ответа на ваш вопрос.