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)、null以外の文字列を返す方法がわかりません。null引数が渡されるとコンストラクターが例外をスローするため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を使用しています)。「GetBundleResponse」ではなく「GenerateBundleResponse」に注意してください。

    [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 に答える