Unité testant une HttpApplication

J’ai une classe dérivée de HttpApplication qui ajoute des fonctionnalités supplémentaires. Je suis sur le sharepoint tester ces fonctionnalités à l’unité, ce qui signifie que je dois être capable de créer une nouvelle instance de HttpApplication, de simuler une requête et de récupérer l’object de réponse.

Comment faire pour que l’unité teste un object HttpApplication? J’utilise Moq pour le moment, mais je ne sais pas comment configurer l’object fictif requirejs.

Malheureusement, cela n’est pas particulièrement facile à faire, car HttpApplication ne se prête pas très bien aux moqueries; il n’y a pas d’interface à simuler et la plupart des méthodes ne sont pas marquées comme virtuelles.

J’ai récemment eu un problème similaire avec HttpRequest et HttpWebResponse. En fin de compte, la solution que j’ai choisie consistait à créer un wrapper de “transmission directe” pour les méthodes que je voulais utiliser:

public class HttpWebRequestWrapper : IHttpWebRequestWrapper { private HttpWebRequest httpWebRequest; public HttpWebRequestWrapper(Uri url) { this.httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); } public Stream GetRequestStream() { return this.httpWebRequest.GetRequestStream(); } public IHttpWebResponseWrapper GetResponse() { return new HttpWebResponseWrapper(this.httpWebRequest.GetResponse()); } public Int64 ContentLength { get { return this.httpWebRequest.ContentLength; } set { this.httpWebRequest.ContentLength = value; } } public ssortingng Method { get { return this.httpWebRequest.Method; } set { this.httpWebRequest.Method = value; } } public ssortingng ContentType { get { return this.httpWebRequest.ContentType; } set { this.httpWebRequest.ContentType = value; } } } 

etc

Cela me permet de me moquer de ma propre interface wrapper. Ce n’est pas nécessairement la chose la plus élégante au monde, mais un moyen très utile de se moquer de certaines des parties les moins “moqueuses” du cadre.

Avant de vous lancer rapidement dans cette voie, il est utile de revoir ce que vous avez obtenu et de voir s’il existe une meilleure approche de vos tests qui vous éviterait de devoir terminer les cours.

Dans le cas de HttpWebRequest, HttpApplication et autres, il n’y a souvent pas d’IMHO.

Afin de définir ce wrapper dans un simulacre (en utilisant mon exemple HttpWebRequest ci-dessus), vous faites alors des choses comme celle-ci avec Moq:

 var mockWebRequest = new Mock(); mockWebRequest.SetupSet(c => c.Method = "POST").Verifiable(); mockWebRequest.SetupSet(c => c.ContentType = "application/x-www-form-urlencoded").Verifiable(); mockWebRequest.SetupSet(c => c.ContentLength = 0).Verifiable(); 

IMHO append une fonctionnalité en étendant HttpApplication n’est pas la meilleure chose à faire. Il est si difficile de se moquer de HttpContext à cause des classes private / internal / sealed que même si vous réussissez vos tests unitaires, vous serez tellement encombré de code moqueur que vous ne pourrez plus comprendre ce que vous testez réellement.

Pourriez-vous donner plus de détails sur les fonctionnalités que vous ajoutez? Peut-être qu’il existe un meilleur moyen d’append cette fonctionnalité à votre application.

J’ai trouvé le blog suivant plus tôt, ce qui explique une approche plutôt sympa avec Microsoft Moles.

http://maraboustork.co.uk/index.php/2011/03/mocking-httpwebresponse-with-moles/

En bref, la solution suggère ce qui suit:

  [TestMethod] [HostType("Moles")] [Description("Tests that the default scraper returns the correct result")] public void Scrape_KnownUrl_ReturnsExpectedValue() { var mockedWebResponse = new MHttpWebResponse(); MHttpWebRequest.AllInstances.GetResponse = (x) => { return mockedWebResponse; }; mockedWebResponse.StatusCodeGet = () => { return HttpStatusCode.OK; }; mockedWebResponse.ResponseUriGet = () => { return new Uri("http://www.google.co.uk/someRedirect.aspx"); }; mockedWebResponse.ContentTypeGet = () => { return "testHttpResponse"; }; var mockedResponse = " \r\n" + "  \r\n" + "  \r\n" + " 

Hello World

\r\n" + " \r\n" + ""; var s = new MemoryStream(); var sw = new StreamWriter(s); sw.Write(mockedResponse); sw.Flush(); s.Seek(0, SeekOrigin.Begin); mockedWebResponse.GetResponseStream = () => s; var scraper = new DefaultScraper(); var retVal = scraper.Scrape("http://www.google.co.uk"); Assert.AreEqual(mockedResponse, retVal.Content, "Should have returned the test html response"); Assert.AreEqual("http://www.google.co.uk/someRedirect.aspx", retVal.FinalUrl, "The finalUrl does not correctly represent the redirection that took place."); }