2009-07-25 4 views
4

J'utilise Moq pour créer un objet fantaisie de HttpResponseBase. Je dois pouvoir tester que HttpResponseBase.End() a été appelé dans ma bibliothèque. Pour ce faire, je spécifie du texte avant l'appel et du texte après. Ensuite, je vérifie que seul le texte avant l'appel à End() est présent dans HttpResponseBase.Output. Le problème est, je ne peux pas comprendre comment se moquer HttpResponseBase.End() pour qu'il arrête le traitement, comme il le fait dans ASP.NET.Comment est-ce que je me moque de HttpResponseBase.End()?

public static HttpResponseBase CreateHttpResponseBase() { 
    var mock = new Mock<HttpResponseBase>(); 
    StringWriter output = new StringWriter(); 

    mock.SetupProperty(x => x.StatusCode); 
    mock.SetupGet(x => x.Output).Returns(output); 
    mock.Setup(x => x.End()) /* what do I put here? */; 
    mock.Setup(x => x.Write(It.IsAny<string>())) 
     .Callback<string>(s => output.Write(s)); 

    return mock.Object; 
} 

Répondre

2

Il est un peu clair pour moi ce que vous essayez d'atteindre, mais à partir de votre description, il semble que vous essayez d'obtenir votre abstraction de se comporter comme une mise en œuvre particulière. En d'autres termes, parce que HttpResponse.End() a un certain comportement, vous voulez que votre Mock ait le même comportement?

En général, ce n'est pas particulièrement facile à faire avec Moq, car il n'a pas de concept d'attentes ordonnées (contrairement à RhinoMocks). Il y a cependant un feature request for it.

Vous pouvez utiliser un rappel avec la configuration de la méthode End pour basculer un indicateur qui détermine tout autre comportement du Mock, mais il ne sera pas particulièrement joli. Je pense à quelque chose comme ceci:

bool ended = false; 
var mock = new Mock<HttpResponseBase>(); 
mock.Setup(x => x.End()).Callback(() => ended = true); 
// Other setups involving 'ended' and Callbacks 

ont alors tous les autres ont une double Setups implementatations selon que ended est vrai ou faux.

Ce serait vraiment sacrément moche, donc je reconsidérerais sérieusement mes options à ce stade. Vous pouvez prendre au moins deux directions:

  1. Effectuez une implémentation Fake de HttpResponseBase au lieu d'utiliser Moq. Il semble que vous attendiez un tel comportement spécifique de l'implémentation qu'un Test Double avec une logique embarquée sonne comme une meilleure option. En bref, un faux est un test double qui peut contenir une logique semi-complexe qui imite l'implémentation de production prévue. Vous pouvez en lire plus sur Fakes et autres tests doubles dans l'excellent livre xUnit Test Patterns.
  2. Ré-examinez vos hypothèses initiales. Il me semble que vous liez votre client de très près à un comportement particulier de HttpResponseBase, de sorte que vous pouvez violer le principe de substitution de Liskov. Cependant, je peux me tromper, car une méthode appelée «End» porte certaines connotations au-delà de la pure sémantique, mais je considérerais personnellement si un meilleur design était possible.
+0

Merci! Définir un drapeau semble être le moyen le plus facile d'y aller. –

Questions connexes