10

O ile mi wiadomo, odpowiedź brzmi "nie". Problem, który widzę, pochodzi z metody Include(params string[]) w klasie System.Web.Optimization.Bundle. Wewnętrznie ten wywołuje System.Web.Optimization.IncludeDirectory(string, string, bool), który z kolei wykorzystuje ten kod:Czy można przetestować zestaw BundleConfig w MVC4?

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

Choć możliwe jest, aby ustawić HttpContext.Current podczas testów jednostkowych, nie mogę dowiedzieć się, jak sprawić, by jej .Server.MapPath(string directoryVirtualPath) powrót non-łańcuch pusty. Ponieważ konstruktor DirectoryInfo(string) generuje wyjątek po przekazaniu zerowego argumentu, taki test zawsze kończy się niepowodzeniem.

Co to jest rekomendacja zespołu .NET? Czy mamy do jednostkowej konfiguracji testowania pakietów w ramach testów integracyjnych lub testów akceptacyjnych użytkowników?

+4

Naprawdę? Czy ja też będę musiał zacząć nagrodę za to? – danludwig

Odpowiedz

9

Mam dobre wieści dla ciebie, dla RTM dodaliśmy nową właściwość statyczną na BundleTable aby umożliwić większej liczbie testów jednostkowych:

public static Func<string, string> MapPathMethod; 

Edit Aktualizacja z testu wirtualnego operatora ścieżki:

Więc możesz zrobić coś takiego:

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

A następnie napisz test jednostkowy, używając następującego wzoru:

[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

Niestety, to obejście nie jest już możliwe w najnowszej wersji, ponieważ MapPathMethod został usunięty. Czy możesz doradzić w sprawie alternatywnej strategii (ewentualnie używając VirtualPathProvider)? –

+1

Pewnie dodałem testowy vpp, którego używam do testów jednostkowych. –

+0

Wygląda na to, że zmieniło się ponownie, nie ma już żadnych elementów Items w pakiecie. – Giedrius

5

W .Net 4.5 pewne rzeczy uległy zmianie. Oto działająca wersja zatwierdzonej odpowiedzi zaktualizowana, aby uwzględnić te zmiany (używam Autofac). Zauważ "GenerateBundleResponse" zamiast "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); 
    }