2017-03-20 22 views
1

所有这些观点甚至没有一个标题。所以我不能做我如何编写单元测试来测试ASP.NET MVC控制器与下面的代码片段

Assert.AreEqual(“Error”,Viewbag.Title);

我还能如何测试一个差错控制,以保证ATLEAST85%代码覆盖

public class ErrorController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    public ActionResult NotFound() 
    { 
     return View(); 
    } 
    public ActionResult BadRequest() 
    { 
     return View(); 
    } 

    public ActionResult ServerError() 
    { 
     return View(); 
    } 
} 

我能想出是

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, ""); 
    } 
} 
+0

您可以对控制器进行测试并检查返回的视图对象。或者你可以使用Selenium来自动化UI测试。 –

+0

你确定你需要100%的代码覆盖率吗?看起来没有必要为这些方法编写单元测试 – Disappointed

+0

为什么你要测试框架而不是你的代码? MS将在发布之前对其进行测试。 – Nkosi

回答

1

基本上,你想测试应该已经被微软谁拥有的框架做了框架。您应该尽量避免测试您不拥有或控制的代码。

这就是说,这里是一个解决办法来测试试图模仿周围的限制框架的功能和工作,当涉及到单元测试的ErrorController

[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; 
    } 

} 
+0

伟大的企图@Nkosi。你似乎在使用Moq。如果你避开它,本来会很好的。不过,回答这个问题。 –

+0

@DLaarasimhan允许框架依赖被相当容易地嘲笑。 – Nkosi

+0

什么模拟的Mock.Of 在你的代码的类型? –

1

您可以将最好的试验中,例如图名:

Assert.AreEqual("Index", result.ViewName); 

但要做到这一点,你需要在行动回报指定视图名称:

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"); 
     } 
    }