I'm implementing an IHttpModule
and am trying to write unit tests for it (using NUnit and Moq). I'm having a problem mocking the HttpApplication
dependency for the Init
method:
void Init(HttpApplication context);
Normally, ASP.NET controls the HttpApplication
instance and passes it to the Init
method. In the Init
method, the custom IHttpModule
subscribes to events published by the HttpApplication
instance (like BeginRequest
and EndRequest
).
I need some way to mock the HttpApplication
so I can raise the events and test that my implementation of the IHttpModule
event handlers work.
I've tried creating a Mock HttpApplication
in my test:
// 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);
...but it gives the following error message:
Expression is not an event attach or detach, or the event is declared in a class but not marked virtual.
When I looked into that error, I learned that Moq can only mock Interfaces and virtual methods... So how can I mock a concrete class that I have no control over?
Here is the MyModule
class:
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;
}
}