如何为方法添加单元测试?
1、在新建MVC项目时为项目添加默认的单元测试项目,如图所示:
2、或者在vs中相应的方法处单击鼠标右键,添加单元测试即可,如图所示:
MVC单元测试
默认生成的单元测试代码已经为Controller生成了相应的单元测试方法,例如对HomeController进行单元测试,注意测试类的命名规范,以及两个特性TestClass和TestMethod,有了这两个东东,方可对类和方法进行测试。我们可以发现是按照arrange/act/assert的模式来进行单元测试的,单元测试说白了就是三步走:arrange:初始化测试的环境属于准备阶段;act:执行测试;assert:断言,测试的结果
[TestClass] public class HomeControllerTest { [TestMethod] public void About() { // Arrange HomeController controller = new HomeController(); // Act ViewResult result = controller.About() as ViewResult; // Assert Assert.IsNotNull(result); } } |
难点其实在第一步,就是测试环境的准备,这里更多的是用Moq来进行模拟。另外,涉及到的Assert类主要有以下这些方法
Assert.Inconclusive() 表示一个未验证的测试;
Assert.AreEqual() 测试指定的值是否相等,如果相等,则测试通过;
AreSame() 用于验证指定的两个对象变量是指向相同的对象,否则认为是错误
AreNotSame() 用于验证指定的两个对象变量是指向不同的对象,否则认为是错误
Assert.IsTrue() 测试指定的条件是否为True,如果为True,则测试通过;
Assert.IsFalse() 测试指定的条件是否为False,如果为False,则测试通过;
Assert.IsNull() 测试指定的对象是否为空引用,如果为空,则测试通过;
Assert.IsNotNull() 测试指定的对象是否为非空,如果不为空,则测试通过;
一个模拟访问Service服务的单元测试栗子:
namespace Mvc4UnitTesting.Tests.Controllers { [TestClass] public class HomeControllerTest { [TestMethod] public void Index() { // Arrange var mockIProductService = new Mock<IProductService>(); mockIProductService.Setup(p => p.GetAllProduct()).Returns(new List<Product> { new Product{ ProductId = 1, ProductName = "APPLE", Price = "5999"}}); HomeController controller = new HomeController(mockIProductService.Object); // Act ViewResult result = controller.Index() as ViewResult; var product = (List<Product>)result.ViewData.Model; // Assert Assert.AreEqual("APPLE", product.First<Product>().ProductName); } } } |
一个模拟访问Web环境的单元测试栗子:
public ActionResult Index() { ViewData["Message"] = Request.QueryString["WW"]; return View(); } [TestMethod] public void Index() { HomeController controller = new HomeController(); var httpContext = new Mock<HttpContextBase>(); var request=new Mock<HttpRequestBase>(); NameValueCollection queryString = new NameValueCollection(); queryString.Add("WW", "WW"); request.Setup(r => r.QueryString).Returns(queryString); httpContext.Setup(ht => ht.Request).Returns(request.Object); ControllerContext controllerContext = new ControllerContext(); controllerContext.HttpContext = httpContext.Object; controller.ControllerContext = controllerContext; ViewResult result = controller.Index() as ViewResult; ViewDataDictionary viewData = result.ViewData; Assert.AreEqual("WW", viewData["Message"]); } |
总结:
有效的测试是软件质量的保证,所以这里希望大家,包括本人自己在内,都能够把单元测试落到实处,目前对于我们来说,最大的难点在于能否恰到好处地模拟出相关的依赖资源,因此写出低耦合的代码就变得很有必要。其实多加练习使用之后,自然就能够应对相对复杂的单元测试,终有一天你会发现,单位测试只不过是分分钟的事!