Proprietà statica fittizia con moq

Sono abbastanza nuovo da usare moq . Sto creando alcuni casi di test unitari su HttpModule e tutto funziona bene finché non colpisco una proprietà static come segue

 this.applicationPath = (HttpRuntime.AppDomainAppVirtualPath.Length > 1) ? HttpRuntime.AppDomainAppVirtualPath : String.Empty; 

Non so come creare mock per classi e proprietà static come HttpRuntime.AppDomainAppVirtualPath . Il context , la request e la response sono stati beffati bene con il codice di esempio che ho ricevuto da moq. Apprezzerò se qualcuno mi può aiutare su questo.

Moq non può falsificare membri statici.

Come soluzione è ansible creare una class wrapper (Pattern adattatore) che trattiene la proprietà statica e falsi i suoi membri.
Per esempio:

 public class HttpRuntimeWrapper { public virtual string AppDomainAppVirtualPath { get { return HttpRuntime.AppDomainAppVirtualPath; } } } 

Nel codice di produzione puoi accedere a questa class invece di HttpRuntime e HttpRuntime questa proprietà:

 [Test] public void AppDomainAppVirtualPathTest() { var mock = new Moq.Mock(); mock.Setup(fake => fake.AppDomainAppVirtualPath).Returns("FakedPath"); Assert.AreEqual("FakedPath", mock.Object.AppDomainAppVirtualPath); } 

Un’altra soluzione è l’utilizzo di Isolation Framework (come Typemock Isolator ) in cui è ansible simulare classi e membri statici.
Per esempio:

 Isolate.WhenCalled(() => HttpRuntime.AppDomainAppVirtualPath) .WillReturn("FakedPath"); 

Disclaimer – Lavoro a Typemock

Non puoi modificare i metodi statici con Moq.

Questa non è una brutta cosa, in realtà, i metodi e le classi statiche hanno il loro posto, ma per la logica rendono difficili i test unitari. Naturalmente li incontrerai quando usi altre librerie. Per aggirare questo problema è necessario scrivere un adattatore (wrapper) attorno al codice statico e fornire un’interfaccia. Per esempio:

 // Your static class - hard to mock class StaticClass { public static int ReturnOne() { return 1; } } // Interface that you'll use for a wrapper interface IStatic { int ReturnOne(); } 

Nota, ho omesso la class concreta che utilizza IStatic per il codice di produzione. Tutto ciò che sarebbe una class che usa IStatic e il tuo codice di produzione farebbe uso di questa class, piuttosto che StaticClass sopra.

Quindi con Moq:

 var staticMock = new Mock(); staticMock.Setup(s => s.ReturnOne()).Returns(2); 

Come menzionato nelle risposte precedenti, non è ansible utilizzare MoQ su metodi statici e, se necessario, la soluzione migliore è creare un wrapper attorno alla class statica.

Tuttavia, qualcosa che ho scoperto di recente è il progetto Moles . Dalla homepage; “Moles consente di sostituire qualsiasi metodo .NET con un delegato. Moles supporta metodi statici o non virtuali.” Potrebbe essere utile per la tua situazione attuale.

La soluzione migliore che ho trovato finora è il JustMock di Telerik – sfortunatamente solo la versione a pagamento consente di prendere in giro la statica.

Mentre l’idea di avvolgere la statica è buona, non puoi sempre farlo. Se si desidera testare del codice che utilizza già alcune classi statiche, non è sempre ansible uscire e utilizzare un wrapper. In questo caso, JustMock sembra una soluzione ragionevole e probabilmente lo userò su alcune soluzioni nel prossimo futuro.

È ansible utilizzare Microsoft Fakes per questo. Risolverà definitivamente il problema. Fare riferimento a https://msdn.microsoft.com/en-us/library/hh549175.aspx