在单元测试中模拟以下代码的最佳方法是什么:
public ActionResult Products() { ViewBag.Title = "Company Product"; IEnumerable<ProductDetailDto> productList = ProductService.GetAllEffectiveProductDetails(); ProductModels.ProductCategoryListModel model = new ProductModels.ProductCategoryListModel { //the type of ProductDetails => IEnumerable<productDetailDto> ProductDetails = ProductService.GetAllEffectiveProductDetails(),//the type of ProductCategoryList => IEnumerable<selectlistitem> ProductCategoryList = productList.Select(x => new SelectListItem { Value = x.FKProductId.ToString(),Text = x.Name }) }; return View(model); }
仅供参考,我正在研究VS 2012,MVC 4.0,使用MOQ对象和TFS设置进行单元测试.
解决方法
如果您想首先模拟ProductService,则需要注入此依赖项.
Constructor injection是ASP.NET MVC中最常用的控制器方法.
public class YourController : Controller { private readonly IProductService ProductService; /// <summary> /// Constructor injection /// </summary> public YourController(IProductService productService) { ProductService = productService; } /// <summary> /// Code of this method has not been changed at all. /// </summary> public ActionResult Products() { ViewBag.Title = "Company Product"; IEnumerable<ProductDetailDto> productList = ProductService.GetAllEffectiveProductDetails(); ProductModels.ProductCategoryListModel model = new ProductModels.ProductCategoryListModel { //the type of ProductDetails => IEnumerable<productDetailDto> ProductDetails = ProductService.GetAllEffectiveProductDetails(),Text = x.Name }) }; return View(model); } } #region DataModels public class ProductDetailDto { public int FKProductId { get; set; } public string Name { get; set; } } public class ProductModels { public class ProductCategoryListModel { public IEnumerable<ProductDetailDto> ProductDetails { get; set; } public IEnumerable<SelectListItem> ProductCategoryList { get; set; } } } #endregion #region Services public interface IProductService { IEnumerable<ProductDetailDto> GetAllEffectiveProductDetails() } public class ProductService : IProductService { public IEnumerable<ProductDetailDto> GetAllEffectiveProductDetails() { throw new NotImplementedException(); } } #endregion
然后,您可以轻松地创建IProductService的模拟实例,将其传递给YourController的构造函数,设置GetAllEffectiveProductDetails方法并检查返回的ActionResult及其模型.
[TestClass] public class YourControllerTest { private Mock<IProductService> productServiceMock; private YourController target; [TestInitialize] public void Init() { productServiceMock = new Mock<IProductService>(); target = new YourController( productServiceMock.Object); } [TestMethod] public void Products() { //arrange // There is a setup of 'GetAllEffectiveProductDetails' // When 'GetAllEffectiveProductDetails' method is invoked 'expectedallProducts' collection is exposed. var expectedallProducts = new List<ProductDetailDto> { new ProductDetailDto() }; productServiceMock .Setup(it => it.GetAllEffectiveProductDetails()) .Returns(expectedallProducts); //act var result = target.Products(); //assert var model = (result as ViewResult).Model as ProductModels.ProductCategoryListModel; Assert.AreEqual(model.ProductDetails,expectedallProducts); /* Any other assertions */ } }