c# – mock HttpContext.Current.Server.MapPath使用Moq?

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上下文,可以隔离测试.呼叫者有责任通过正确的路径.

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...