10

据我所知,答案是否定的。我看到的问题来自课堂上的Include(params string[])方法System.Web.Optimization.Bundle。这在内部调用System.Web.Optimization.IncludeDirectory(string, string, bool),而后者又使用以下代码:

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

虽然可以HttpContext.Current在单元测试期间进行设置,但我不知道如何使其.Server.MapPath(string directoryVirtualPath)返回非空字符串。由于DirectoryInfo(string)构造函数在传递空参数时会抛出异常,因此这样的测试总是会失败。

.NET 团队对此有何建议?作为集成测试或用户验收测试的一部分,我们是否必须对捆绑配置进行单元测试?

4

2 回答 2

9

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

public static Func<string, string> MapPathMethod;

编辑使用测试虚拟路径提供程序更新:

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

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;
            }
        }
    }

然后像这样使用它编写一个单元测试:

    [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);
    }
于 2012-07-11T20:32:37.393 回答
6

在 .Net 4.5 中,情况略有变化。这是已更新以适应这些更改的已批准答案的工作版本(我正在使用 Autofac)。注意“GenerateBundleResponse”而不是“GetBundleResponse”:

    [Fact]
    public void StyleBundleIncludesVersion()
    {
        //Setup the vpp to contain the files/directories
        var 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
        var bundleCollection = new BundleCollection();
        var bundle = new ScriptBundle("~/bundles/test");
        BundleTable.VirtualPathProvider = vpp;
        bundle.Include("~/dir/style{version}.css");
        bundleCollection.Add(bundle);
        var mockHttpContext = new Mock<HttpContextBase>();

        // Verify the bundle repsonse
        var context = new BundleContext(mockHttpContext.Object, bundleCollection, vpp.ToString());
        var response = bundle.GenerateBundleResponse(context);
        Assert.Equal(@"correct", response.Content);
    }
于 2014-03-01T17:06:41.967 回答