Я реализую IHttpModule
и пытаюсь написать для него модульные тесты (используя NUnit и Moq). У меня проблема с подделкой зависимости HttpApplication
для метода Init
:
void Init(HttpApplication context);
Обычно ASP.NET контролирует экземпляр HttpApplication
и передает его методу Init
. В методе Init
пользовательский IHttpModule
подписывается на события, опубликованные экземпляром HttpApplication
(например, BeginRequest
и EndRequest
).
Мне нужен какой-то способ смоделировать HttpApplication
, чтобы я мог вызывать события и проверять, работает ли моя реализация обработчиков событий IHttpModule
.
Я пытался создать макет HttpApplication
в моем тесте:
// Mock for the logging dependency
var mockLogger = new Mock<ILogger>();
// My attempt at mocking the HttpApplication
var mockApplication = new Mock<HttpApplication>();
// MyModule is my class that implements IHttpModule
var myModule = new MyModule(mockLogger.Object);
// Calling Init, which subscribes my event handlers to the HttpApplication events
myModule.Init(mockApplication.Object);
// Attempting to raise the begin and end request events
mockApplication.Raise(a => a.BeginRequest += null, EventArgs.Empty);
mockApplication.Raise(a => a.EndRequest += null, EventArgs.Empty);
// RequestTime is a long property that tracks the time it took (in miliseconds) for a
// request to be processed and is set in the event handler subscribed to EndRequest
Assert.Greater(myModule.RequestTime, 0);
... но выдает следующее сообщение об ошибке:
Выражение не является присоединением или отсоединением события, или событие объявлено в классе, но не помечено как виртуальное.
Когда я посмотрел на эту ошибку, я узнал, что Moq может только издеваться над интерфейсами и виртуальными методами ... Так как же я могу издеваться над конкретным классом, который я не могу контролировать?
Вот класс MyModule
:
public class MyModule : IHttpModule
{
ILogger _logger;
public long RequestTime { get; private set; }
Stopwatch _stopwatch;
public MyModule(ILogger logger)
{
_logger = logger;
}
public void Init(HttpApplication context)
{
context.BeginRequest += OnBeginRequest;
context.EndRequest += OnEndRequest;
}
public void Dispose() { }
void OnBeginRequest(object sender, EventArgs e)
{
_stopwatch = Stopwatch.StartNew();
}
void OnEndRequest(object sender, EventArgs e)
{
_stopwatch.Stop();
RequestTime = _stopwatch.ElapsedMilliseconds;
}
}