Je suis assez nouveau pour utiliser moq . Je suis en train de créer un scénario de test unitaire pour HttpModule
et tout fonctionne correctement jusqu'à ce que je clique sur une propriété static
comme suit
this.applicationPath = (HttpRuntime.AppDomainAppVirtualPath.Length > 1) ? HttpRuntime.AppDomainAppVirtualPath : String.Empty;
Je ne sais pas comment créer des exemples pour static
classe et propriété comme HttpRuntime.AppDomainAppVirtualPath
. Les context
, request
et response
ont été bien moqués avec l'exemple de code que je reçois de moq. J'apprécierai si quelqu'un peut m'aider à ce sujet.
Moq ne peut pas simuler de membres statiques.
En tant que solution, vous pouvez créer une classe wrapper (Adapter Pattern) contenant la propriété static et simuler ses membres.
Par exemple:
public class HttpRuntimeWrapper
{
public virtual string AppDomainAppVirtualPath
{
get
{
return HttpRuntime.AppDomainAppVirtualPath;
}
}
}
Dans le code de production, vous pouvez accéder à cette classe au lieu de HttpRuntime
et simuler cette propriété:
[Test]
public void AppDomainAppVirtualPathTest()
{
var mock = new Moq.Mock<HttpRuntimeWrapper>();
mock.Setup(fake => fake.AppDomainAppVirtualPath).Returns("FakedPath");
Assert.AreEqual("FakedPath", mock.Object.AppDomainAppVirtualPath);
}
Une autre solution consiste à utiliser le cadre d’isolation (sous la forme Typemock Isolator ) dans lequel vous pouvez simuler des classes et des membres statiques.
Par exemple:
Isolate.WhenCalled(() => HttpRuntime.AppDomainAppVirtualPath)
.WillReturn("FakedPath");
Disclaimer - Je travaille chez Typemock
Vous ne pouvez pas utiliser les méthodes statiques Moq avec Moq.
Ce n'est pas une mauvaise chose en réalité: les méthodes et les classes statiques ont leur place, mais pour la logique, elles rendent les tests unitaires difficiles. Naturellement, vous les rencontrez lorsque vous utilisez d'autres bibliothèques. Pour résoudre ce problème, vous devez écrire un adaptateur (wrapper) autour du code statique et fournir une interface. Par exemple:
// 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();
}
Remarque, j'ai omis la classe concrète qui utilise IStatic pour le code de production. Allit serait une classe qui utilise IStatic et votre code de production utiliserait cette classe plutôt que StaticClass
ci-dessus.
Puis avec Moq:
var staticMock = new Mock<IStatic>();
staticMock.Setup(s => s.ReturnOne()).Returns(2);
Comme mentionné dans les réponses précédentes, vous ne pouvez pas utiliser MoQ sur des méthodes statiques. Si vous en avez le besoin, votre meilleure idée consiste à créer un wrapper autour de la classe statique.
Cependant, quelque chose que j'ai découvert récemment est le projet Moles . De la page d'accueil; "Moles permet de remplacer n'importe quelle méthode .NET par un délégué. Moles supporte les méthodes statiques ou non virtuelles." Cela pourrait être utile pour votre situation actuelle.
La meilleure solution que j’ai trouvée jusqu’à présent est celle de Telerik JustMock - malheureusement, seule la version payante permet de se moquer de la statique.
Bien que l'idée d'encapsuler la statique soit bonne, vous ne pouvez pas toujours le faire. Si vous souhaitez tester du code qui utilise déjà des classes statiques, il n'est pas toujours possible de basculer et d'utiliser un wrapper. Dans ce cas, JustMock semble une solution raisonnable et je vais probablement l’utiliser dans un avenir proche.
Vous pouvez utiliser Microsoft Fakes pour cela. Cela résoudra définitivement le problème. Reportez-vous à https://msdn.Microsoft.com/en-us/library/hh549175.aspx
Utiliser Microsoft Fakes comme suggéré par @Sujith est une solution viable. Voici comment vous le faites réellement:
System.Web
dans votre référence de votre projet test et faites un clic droit.System.Web.4.0.0.0.Fakes
Utilisez le code suivant:
using (Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create ()) { System.Web.Fakes.ShimHttpRuntime.AppDomainAppVirtualPathGet = () => "/"; // Faites ce qui est nécessaire pour le faux AppDomainAppVirtualPath }