10

Per quanto ne so, la risposta è no. Il problema riscontrato è il metodo Include(params string[]) nella classe System.Web.Optimization.Bundle. Internamente viene invocato System.Web.Optimization.IncludeDirectory(string, string, bool), che a sua volta utilizza questo codice:È possibile testare unitamente BundleConfig in MVC4?

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

Mentre è possibile impostare HttpContext.Current durante un test di unità, non riesco a capire come fare sua .Server.MapPath(string directoryVirtualPath) ritorno una stringa non nulla. Poiché il costruttore DirectoryInfo(string) genera un'eccezione quando viene passato un argomento nullo, tale test fallirà sempre.

Qual è la raccomandazione del team .NET per questo? Dobbiamo eseguire il test unitario delle configurazioni di bundling come parte dei test di integrazione o dei test di accettazione degli utenti?

+4

Davvero? Devo iniziare una taglia su questo anche ??? – danludwig

risposta

9

ho qualche buona notizia per voi, per RTM abbiamo aggiunto una nuova proprietà statica su BundleTable per permettere a più test di unità:

public static Func<string, string> MapPathMethod; 

Modifica aggiornato con una prova virtuale provider di percorso:

Quindi puoi fare qualcosa del genere:

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

E poi scrivere un test di unità usando così:

[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); 
    } 
+1

Sfortunatamente, questa soluzione alternativa non è più possibile nella versione più recente perché MapPathMethod è stato rimosso. Puoi consigliare una strategia alternativa (possibilmente utilizzando un VirtualPathProvider)? –

+1

Sure ha aggiunto il test vpp che uso per i test unitari –

+0

Sembra che sia cambiato di nuovo, non ci sia più nessuna proprietà Items in bundle. – Giedrius

5

In .Net 4.5 le cose sono leggermente cambiate. Ecco una versione funzionante della risposta approvata aggiornata per accogliere queste modifiche (sto usando Autofac). Nota "GenerateBundleResponse" invece di "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); 
    }