I'm using Visual Studio 2010 Ultimate SP1. I have around 225 unit tests in my project, and they are all passing. One of those tests, however, reports 0% code coverage for the method it hits. When debugging, I can step through and see that it hits every line of the method. Yet in the code coverage report, it shows that the method isn't covered at all. All other tests and methods work just fine with regards to code coverage.
I've tried the following with no success:
- Moved the method being tested into another class.
- Made the method
- static vs. non-static.
- Moved the test to another class.
- Deleted all of my .testsetting files and recreated them from scratch
- Wrote a different test to exercise the same method, with the same results
- restarted VS
- rebooted
In case it matters, the method was in the Global.asax file. However, I moved it to another class and it made no difference.
Any ideas?
Here is the method being tested.
public void LogError(ILoggingService loggingService, IController controller)
{
if (loggingService == null)
throw new ArgumentNullException("loggingService");
if (controller == null)
throw new ArgumentNullException("controller");
Exception ex = Server.GetLastError();
loggingService.LogException(ex.Message, ex.StackTrace, ApplicationName.VoucherLog, UserInfo.UserName);
HttpException httpException = ex as HttpException;
if (httpException == null)
{
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "HttpError";
Server.ClearError();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
controller.Execute(rc);
}
}
The first 4 lines, where the exceptions are thrown, are hit by other tests and show up in the code coverage statistics. The remainder of the method is hit by the following test (as verified by debugging through it and seeing that each and every line is, in fact, executed), but does not show up in code coverage stats. Here is the test:
[TestMethod]
[HostType("Moles")]
public void LogError()
{
DMVCommon.ApplicationName expectedApplication = DMVCommon.ApplicationName.VoucherLog;
string expectedUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
NotImplementedException expectedException = null;
System.Web.Moles.MHttpServerUtility.AllInstances.GetLastError = (System.Web.HttpServerUtility server) =>
{
return expectedException;
};
System.Web.Moles.MHttpApplication.AllInstances.ContextGet = (System.Web.HttpApplication application) =>
{
return MvcMockHelpers.FakeHttpCurrentContext();
};
try
{
throw new NotImplementedException();
}
catch (NotImplementedException exc)
{
expectedException = exc;
using (MvcApplication app = new MvcApplication())
{
bool called = false;
Mock<ILoggingService> mockLoggingService = new Mock<ILoggingService>();
mockLoggingService.Setup(a => a.LogException(expectedException.Message, expectedException.StackTrace, expectedApplication, expectedUser)).Callback(() => called = true);
Mock<IController> mockController = new Mock<IController>();
app.LogError(mockLoggingService.Object, mockController.Object);
mockController.Verify(a => a.Execute(It.IsAny<System.Web.Routing.RequestContext>()), Times.Exactly(1));
Assert.IsTrue(called);
}
}
}