[MVC5] First Unit Test, mvc5unit
1. Controller Test
Note:
1. Do not include business logic in the Controller
2. Passing service dependencies through Constructors
Example:MathControllerThere is an AddAction
using FirstUnitTest.Services;using System.Web.Mvc;namespace FirstUnitTest.Controllers{ public class MathController : Controller { IMathService _service; public MathController(IMathService service) { _service = service; } // GET: Math public RedirectToRouteResult Index() { return RedirectToAction("Add"); //return View(); } [HttpGet] public ActionResult Add() { return View(); } [HttpPost] public ViewResult Add(int left, int right) { ViewBag.Result = _service.Add(left, right); return View(); } }}
IMathServiceThe following is a summation method:
namespace FirstUnitTest.Services{ public interface IMathService { int Add(int left, int right); }}
Write a false Service to provide the Controller with a false business logic layer.
using FirstUnitTest.Services;namespace FirstUnitTest.Tests.Services{ public class SpyMathService : IMathService { public int Add_Left; public int Add_Right; public int Add_Result; public int Add(int left, int right) { Add_Left = left; Add_Right = right; return Add_Result; } }}
Note: The preceding SpyService does not sum two values, because we only pay attention to the Input and Output of MathService (Input is the left and right parameters, and Output is the return value ).
Test method:
[TestMethod]public void AddUseMathService(){ SpyMathService service = new SpyMathService() { Add_Result = 42 }; MathController controller = new MathController(service); ViewResult result = controller.Add(4, 12); Assert.AreEqual(service.Add_Result, result.ViewBag.Result); Assert.AreEqual(4, service.Add_Left); Assert.AreEqual(12, service.Add_Right);}
Redirect test (Index Action in MathController above ):
[TestMethod]public void RedirectToAdd(){ SpyMathService service = new SpyMathService(); MathController controller = new MathController(service); RedirectToRouteResult result = controller.Index(); Assert.AreEqual("Add", result.RouteValues["action"]);}2. Route Test
The default MVC project route is as follows:
using System.Web.Mvc;using System.Web.Routing;namespace FirstUnitTest{ public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }}
Test method:
Using Microsoft. visual Studio. testTools. unitTesting; using Moq; using System. web; using System. web. mvc; using System. web. routing; namespace FirstUnitTest. tests. routes {[TestClass] public class RouteTest {// <summary> // test the IngoreRoute function call // </summary> [TestMethod] public void RouteForEmbeddedResource () {// Arrange var mockContext = new Mock <HttpContextBase> (); mockContext. setup (c => c. request. appRel AtiveCurrentExecutionFilePath). Returns ("~ /Handler. axd "); var routes = new RouteCollection (); // MvcApplication. registerRoutes (routes); RouteConfig. registerRoutes (routes); // Act RouteData routeData = routes. getRouteData (mockContext. object); // Assert. isNotNull (routeData); Assert. isInstanceOfType (routeData. routeHandler, typeof (StopRoutingHandler);} // <summary> // test the MapRoute function call // </summary> [TestMethod] public void RouteToHome Pae () {// Arrange var mockContext = new Mock <HttpContextBase> (); mockContext. Setup (c => c. Request. AppRelativeCurrentExecutionFilePath). Returns ("~ /"); Var routes = new RouteCollection (); RouteConfig. registerRoutes (routes); // Act RouteData routeData = routes. getRouteData (mockContext. object); // Assert. isNotNull (routeData); Assert. areEqual ("Home", routeData. values ["controller"]); Assert. areEqual ("Index", routeData. values ["action"]); Assert. areEqual (UrlParameter. optional, routeData. values ["id"]);} // you do not need to write test code for unmatched routes }}
To use Mock, you need to install the Moq package (you need to set the ProjectName parameter; otherwise, the package will be installed to the Web project by default)
Install-Package moq -ProjectName FirstUnitTest.Tests
3. Verification Test
Movie model:
using System.ComponentModel.DataAnnotations;using System.Data.Entity;namespace FirstUnitTest.Models{ public class Movie { public int Id { get; set; } [Required] public string Title { get; set; } [Required] [Range(1920, 2015)] public int ReleaseYear { get; set; } public int RunTime { get; set; } } public class MovieDb : DbContext { public DbSet<Movie> Movies { get; set; } }}
Property Verification:
Using System; using Microsoft. visual Studio. testTools. unitTesting; using FirstUnitTest. models; using System. componentModel. dataAnnotations; namespace FirstUnitTest. tests. validation {[TestClass] public class MovieValidationTest {[TestMethod] public void TitleRequireTest () {System. threading. thread. currentThread. currentUICulture = new System. globalization. cultureInfo ("zh-cn"); Movie movie = new Movie (); ValidationContext context = new ValidationContext (movie, null, null) {DisplayName = "Title", MemberName = "Title" ,}; RequiredAttribute validator = new RequiredAttribute (); try {validator. validate (movie. title, context);} catch (ValidationException ex) {// the language of the error message is determined by the current thread's CurrentUICulture Assert. areEqual ("the Title field is required. ", Ex. Message); // throw ;}}}}
※Reference ASP. net mvc 5 advanced programming (version 5th)