Учитывая следующую функцию:
public static void Write(HttpContextBase contextBase, IUnitOfWork unitOfWork, LogLevel level, string title, string message, params AdditionalProperty[] properties)
{
// Some variables that are set for writing the logs.
// - client: When the HttpContext is null, 'N.A.' is used, otherwise the I.P. address of the requesting computer.
// - userIdentifier: When the HttpContext exists and a value is stored in the cookie, the value of the cookie, otherwise an empty guid.
// - requestIdentifier: When the context is existing and a request have been made on a controller, a unique value identifying this request, otherwise an empty guid.
string client = (contextBase.ApplicationInstance == null || contextBase.ApplicationInstance.Context.CurrentHandler == null) ? "N.A." : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
string userIdentifier = (contextBase.ApplicationInstance != null && contextBase.ApplicationInstance.Context != null && contextBase.ApplicationInstance.Context.CurrentHandler != null && CookieManager.Exists("UserIdentifier")) ? CookieManager.Read("UserIdentifier", Guid.NewGuid().ToString().ToUpper()) : Guid.Empty.ToString();
string requestIdentifier = (contextBase.ApplicationInstance != null && contextBase.ApplicationInstance.Context != null && contextBase.ApplicationInstance.Context.Cache != null && HttpContext.Current.Cache["RequestIdentifier"] != null) ? HttpContext.Current.Cache["RequestIdentifier"].ToString() : Guid.Empty.ToString();
// Additional code for processing is done here.
}
Я использую HttpContextBase и интерфейс для Unit of Work, так как я знаю, что легче тестировать единицы, чем.
Теперь я использую Moq для использования функциональности Mocking в своем модульном тесте, и я борюсь с ним.
Посмотрим на переменную cliënt:
string client = (contextBase.ApplicationInstance == null || contextBase.ApplicationInstance.Context.CurrentHandler == null) ? "N.A." : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
Я хотел бы знать, как настроить мой unit тест (ы), насмехаясь над необходимыми объектами.
Здесь мой текущий unit тест:
var context = new Mock<HttpContextBase>();
var httpApplicationMock = new Mock<HttpApplication>();
httpApplicationMock.SetupGet(x => x.Context).Returns(context.Object); --> FAILS
context.SetupGet(c => c.ApplicationInstance).Returns(httpApplicationMock.Object);
Настройка httpApplicationMock не выполняется, потому что context.Object не является допустимым параметром, но мне нужно передать HttpContext.
Может кто-нибудь дать мне немного, нежный толчок в правильном направлении?
После некоторых дальнейших тестов я понял, что это не так.
Прежде всего, и, что немаловажно, я использую MSTest. Поэтому проблема не связана с созданием репозитория в конструкторе, потому что для каждого теста, запускаемого через MSTest, выполняется конструктор. Так что это устранено.
После некоторой дополнительной проверки я понял, что для извлечения настроек из репозитория настроек я использую класс, созданный как Singleton, и это было проблемой.
Когда я запускаю свой первый файл с модульным тестом с указанным параметром, все шло отлично, так как все еще нужно было создать настройку.
Но во втором файле я использую другие настройки, но поскольку менеджер, отвечающий за получение настроек, является Singleton, новые настройки не были получены, а вместо этого использовались настройки из предыдущего.
Это вызвало проблему.
В любом случае, благодаря людям, которые пытались помочь мне в этой ситуации.
Эта строка не работает, потому что Context
возвращает тип HttpContext
, а не HttpContextBase
.
httpApplicationMock.SetupGet(x => x.Context).Returns(context.Object);
Создание context
как экземпляра Mock<HttpContext>
не поможет ни потому, что он запечатанный класс, а Moq не могут высмеять закрытые классы.
Вы можете скрыть детали реализации, касающиеся HttpContext за интерфейсом. Здесь сообщение в блоге, которое показывает вам пример: http://volaresystems.com/Blog/post/2010/08/19/Dont-mock-HttpContext