Reputation: 733
All of these views don't even have a title. So I cannot do an
Assert.AreEqual("Error",Viewbag.Title);
How else can I test an error controller to ensure atleast 85% code is covered
public class ErrorController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult NotFound()
{
return View();
}
public ActionResult BadRequest()
{
return View();
}
public ActionResult ServerError()
{
return View();
}
}
The best I could come up with was
public class ErrorControllerTests : BaseTestController
{
ErrorController ec = new ErrorController();
[TestMethod()]
public void IndexTest()
{
var actionResult = ec.Index() as ViewResult;
Assert.AreSame(ec.ViewData, actionResult.ViewData);
Assert.AreSame(ec.TempData, actionResult.TempData);
Assert.AreEqual(actionResult.ViewName,"");
}
[TestMethod()]
public void NotFoundTest()
{
var NotFoundTestResult = ec.NotFound() as ViewResult;
Assert.AreEqual(NotFoundTestResult.ViewName,"");
}
[TestMethod()]
public void BadRequestTest()
{
var badRequestTestResult = ec.BadRequest() as ViewResult;
Assert.AreEqual(badRequestTestResult.ViewName,"");
}
[TestMethod()]
public void ServerErrorTest()
{
var serverErrorTestResult = ec.ServerError() as ViewResult;
Assert.AreEqual(serverErrorTestResult.ViewName, "");
}
}
Upvotes: 2
Views: 1588
Reputation: 247153
You basically trying to test the Framework which should have already been done by Microsoft who owns the framework. You should try to avoid testing code you don't own or control.
That said, here is a work around to test the ErrorController
that tries to mimic framework functionality and work around the limitations when it comes to unit tests.
[TestClass]
public class ErrorControllerTests {
[TestMethod]
public void TestIndexView() {
//Arrange
var expectedViewName = GetViewNameFromExpression<ErrorController>(c => c.Index());
var controller = ArrangeErrorController(expectedViewName);
//Act
var result = controller.Index() as ViewResult;
//Assert
Assert.IsNotNull(result);
//Replicating Framework functionality
MockExecuteResult(controller, result);
Assert.AreEqual(expectedViewName, result.ViewName);
CollectionAssert.AreEquivalent(controller.ViewData.ToList(), result.ViewData.ToList());
CollectionAssert.AreEquivalent(controller.TempData.ToList(), result.TempData.ToList());
}
private static void MockExecuteResult(ErrorController controller, ViewResult result) {
try {
result.View = Mock.Of<IView>();
result.ExecuteResult(controller.ControllerContext);
} catch { }
}
private static ErrorController ArrangeErrorController(string actionName) {
var controllerName = "error";
var context = GetControllerContext(actionName, controllerName);
var controller = new ErrorController() {
ControllerContext = context
};
context.Controller = controller;
return controller;
}
private static ControllerContext GetControllerContext(string actionName, string controllerName) {
RouteData rd = new RouteData();
rd.Values["action"] = actionName;
rd.Values["controller"] = controllerName;
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.Session).Returns((HttpSessionStateBase)null);
mockHttpContext.Setup(_ => _.Response.Output).Returns(new StringWriter());
return new ControllerContext(mockHttpContext.Object, rd, new Mock<Controller>().Object);
}
private static string GetViewNameFromExpression<TController>(Expression<Action<TController>> action) {
if (action == null) {
throw new ArgumentNullException("action");
}
var type = typeof(TController);
bool isController = type != null
&& type.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)
&& !type.IsAbstract
&& typeof(IController).IsAssignableFrom(type);
if (!isController) {
throw new InvalidOperationException("Invalid controller.");
}
MethodCallExpression body = action.Body as MethodCallExpression;
if (body == null)
throw new InvalidOperationException("Expression must be a method call.");
if (body.Object != action.Parameters[0])
throw new InvalidOperationException("Method call must target lambda argument.");
string actionName = body.Method.Name;
return actionName;
}
}
Upvotes: 2
Reputation: 170
You can test for example view name:
Assert.AreEqual("Index", result.ViewName);
But to do that, you need to specify view name in action return:
public class ErrorController : Controller
{
public ActionResult Index()
{
return View("Index");
}
public ActionResult NotFound()
{
return View("NotFound");
}
public ActionResult BadRequest()
{
return View("BadRequest");
}
public ActionResult ServerError()
{
return View("ServerError");
}
}
Upvotes: 1