是否有可能进行单元测试BundleConfig在MVC4? [英] Is it possible to unit test BundleConfig in MVC4?

查看:285
本文介绍了是否有可能进行单元测试BundleConfig在MVC4?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,答案是否定的。我看到的问题来自于包含(PARAMS字符串[])方法在 System.Web.Optimization.Bundle 类。这在内部调用 System.Web.Optimization.IncludeDirectory(字符串,字符串,布尔),这反过来使用这个code:

As far as I can tell, the answer is no. The issue I'm seeing comes from the Include(params string[]) method in the System.Web.Optimization.Bundle class. Internally this invokes System.Web.Optimization.IncludeDirectory(string, string, bool), which in turn uses this code:

DirectoryInfo directoryInfo = new DirectoryInfo(
    HttpContext.Current.Server.MapPath(directoryVirtualPath));

虽然可能一个单元测试过程中设置 HttpContext.Current ,我无法弄清楚如何使其 .Server.MapPath (字符串directoryVirtualPath)返回一个非空字符串。因为 DirectoryInfo的(字符串)构造函数时传递空参数抛出一个异常,这样的测试总是会失败。

While it is possible to set HttpContext.Current during a unit test, I can't figure out how to make its .Server.MapPath(string directoryVirtualPath) return a non-null string. Since the DirectoryInfo(string) constructor throws an exception when passed a null argument, such a test will always fail.

什么是.NET团队的建议为这个?我们有单元测试捆绑配置,集成测试或用户验收测试的一部分?

What is the .NET team's recommendation for this? Do we have to unit test bundling configurations as part of integration tests or user acceptance tests?

推荐答案

我对你有一些好消息RTM我们上添加了一个新的静态属性 BundleTable 启用更多的单元测试:

I have some good news for you, for RTM we added a new static property on BundleTable to enable more unit tests:

public static Func<string, string> MapPathMethod;

修改更新与测试虚拟路径提供:

Edit Updated with a test virtual path provider:

所以,你可以做这样的事情:

So you can do something like this:

public class TestVirtualPathProvider : VirtualPathProvider {

    private string NormalizeVirtualPath(string virtualPath, bool isDirectory = false) {
        if (!virtualPath.StartsWith("~")) {
            virtualPath = "~" + virtualPath;
        }
        virtualPath = virtualPath.Replace('\\', '/');
        // Normalize directories to always have an ending "/"
        if (isDirectory && !virtualPath.EndsWith("/")) {
            return virtualPath + "/";
        }
        return virtualPath;
    }

    // Files on disk (virtualPath -> file)
    private Dictionary<string, VirtualFile> _fileMap = new Dictionary<string, VirtualFile>();
    private Dictionary<string, VirtualFile> FileMap {
        get { return _fileMap; }
    }

    public void AddFile(VirtualFile file) {
        FileMap[NormalizeVirtualPath(file.VirtualPath)] = file;
    }

    private Dictionary<string, VirtualDirectory> _directoryMap = new Dictionary<string, VirtualDirectory>();
    private Dictionary<string, VirtualDirectory> DirectoryMap {
        get { return _directoryMap; }
    }

    public void AddDirectory(VirtualDirectory dir) {
        DirectoryMap[NormalizeVirtualPath(dir.VirtualPath, isDirectory: true)] = dir;
    }

    public override bool FileExists(string virtualPath) {
        return FileMap.ContainsKey(NormalizeVirtualPath(virtualPath));
    }

    public override bool DirectoryExists(string virtualDir) {
        return DirectoryMap.ContainsKey(NormalizeVirtualPath(virtualDir, isDirectory: true));
    }

    public override VirtualFile GetFile(string virtualPath) {
        return FileMap[NormalizeVirtualPath(virtualPath)];
    }

    public override VirtualDirectory GetDirectory(string virtualDir) {
        return DirectoryMap[NormalizeVirtualPath(virtualDir, isDirectory: true)];
    }

    internal class TestVirtualFile : VirtualFile {
        public TestVirtualFile(string virtualPath, string contents)
            : base(virtualPath) {
            Contents = contents;
        }

        public string Contents { get; set; }

        public override Stream Open() {
            return new MemoryStream(UTF8Encoding.Default.GetBytes(Contents));
        }
    }

    internal class TestVirtualDirectory : VirtualDirectory {
        public TestVirtualDirectory(string virtualPath)
            : base(virtualPath) {
        }

        public List<VirtualFile> _directoryFiles = new List<VirtualFile>();
        public List<VirtualFile> DirectoryFiles {
            get {
                return _directoryFiles;
            }
        }

        public List<VirtualDirectory> _subDirs = new List<VirtualDirectory>();
        public List<VirtualDirectory> SubDirectories {
            get {
                return _subDirs;
            }
        }

        public override IEnumerable Files {
            get {
                return DirectoryFiles;
            }
        }

        public override IEnumerable Children {
            get { throw new NotImplementedException(); }
        }

        public override IEnumerable Directories {
            get { 
                return SubDirectories;
            }
        }
    }

,然后使用像这么写单元测试:

And then write a unit test using that like so:

    [TestMethod]
    public void StyleBundleCustomVPPIncludeVersionSelectsTest() {
        //Setup the vpp to contain the files/directories
        TestVirtualPathProvider vpp = new TestVirtualPathProvider();
        var directory = new TestVirtualPathProvider.TestVirtualDirectory("/dir/");
        directory.DirectoryFiles.Add(new TestVirtualPathProvider.TestVirtualFile("/dir/style1.0.css", "correct"));
        directory.DirectoryFiles.Add(new TestVirtualPathProvider.TestVirtualFile("/dir/style.css", "wrong"));
        vpp.AddDirectory(directory);

        // Setup the bundle
        ScriptBundle bundle = new ScriptBundle("~/bundles/test");
        bundle.Items.VirtualPathProvider = vpp;
        bundle.Include("~/dir/style{version}.css");

        // Verify the bundle repsonse
        BundleContext context = SetupContext(bundle, vpp);
        BundleResponse response = bundle.GetBundleResponse(context);
        Assert.AreEqual(@"correct", response.Content);
    }

这篇关于是否有可能进行单元测试BundleConfig在MVC4?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆