im单元测试我的家庭控制器.此测试工作正常,直到我添加了一个保存图像的新功能.
导致问题的方法如下.
public static void SaveStarCarCAPImage(int capID) { byte[] capBinary = Motorpoint2011Data.RetrieveCapImageData(capID); if (capBinary != null) { MemoryStream ioStream = new MemoryStream(); ioStream = new MemoryStream(capBinary); // save the memory stream as an image // Read in the data but do not close,before using the stream. using (Stream originalBinaryDataStream = ioStream) { var path = HttpContext.Current.Server.MapPath("/StarVehiclesImages"); path = System.IO.Path.Combine(path,capID + ".jpg"); Image image = Image.FromStream(originalBinaryDataStream); Image resize = image.GetThumbnailImage(500,375,null,new IntPtr()); resize.Save(path,System.Drawing.Imaging.ImageFormat.Jpeg); } } }
当调用来自单元测试时,HttpContext.Current为null并抛出异常.在阅读有关Moq和有关使用Moq与会话的一些教程之后,确保可以完成.
到目前为止,这个单元测试代码已经提出,但是问题是HTTPContext.Current总是为空,并且仍然抛出异常.
protected ControllerContext CreateStubControllerContext(Controller controller) { var httpContextStub = new Mock<HttpContextBase> { DefaultValue = DefaultValue.Mock }; return new ControllerContext(httpContextStub.Object,new RouteData(),controller); } [TestMethod] public void Index() { // Arrange HomeController controller = new HomeController(); controller.SetFakeControllerContext(); var context = controller.HttpContext; Mock.Get(context).Setup(s => s.Server.MapPath("/StarVehiclesImages")).Returns("My Path"); // Act ViewResult result = controller.Index() as ViewResult; // Assert HomePageModel model = (HomePageModel)result.Model; Assert.AreEqual("Welcome to ASP.NET MVC!",model.Message); Assert.AreEqual(typeof(List<Vehicle>),model.VehicleMakes.GetType()); Assert.IsTrue(model.VehicleMakes.Exists(x => x.Make.Trim().Equals("Ford",StringComparison.OrdinalIgnoreCase))); }
解决方法
HttpContext.Current是你绝对不会使用的东西,如果你期望你的代码进行单元测试.这是一个静态方法,如果没有Web上下文,只需返回null,这是单元测试的情况,不能被嘲笑.因此,重构代码的一种方法如下:
public static void SaveStarCarCAPImage(int capID,string path) { byte[] capBinary = Motorpoint2011Data.RetrieveCapImageData(capID,path); if (capBinary != null) { MemoryStream ioStream = new MemoryStream(); ioStream = new MemoryStream(capBinary); // save the memory stream as an image // Read in the data but do not close,before using the stream. using (Stream originalBinaryDataStream = ioStream) { path = System.IO.Path.Combine(path,capID + ".jpg"); Image image = Image.FromStream(originalBinaryDataStream); Image resize = image.GetThumbnailImage(500,new IntPtr()); resize.Save(path,System.Drawing.Imaging.ImageFormat.Jpeg); } } }
你看,现在这种方法不再依赖于任何Web上下文,可以隔离测试.呼叫者有责任通过正确的路径.