Scrivere test con Visual Studio 2005 non è cosi semplice come per le successive versioni (VS 2008 e 2010). Se state lavorando ad una web-application ed il codice da testare ha uno stretto legame con la cache del server web, il problema si complica molto. Utilizzare NUnit non basta, i test solitamente vengono gestiti in una libreria a parte, motivo per cui non è possibile avere accesso ad un HttpContext, le ripercussioni sono tantissime, prima tra tutte l’assenza della Cache e quindi l’impossibilità di testare il codice che si relaziona direttamente con questa.

Attenzione
Una prima soluzione potrebbe essere l’utilizzo di wrapper che vanno a sostituire gli oggetti che a noi servono, ma se il test necessita di un reale HttpContext con cui eseguire verifiche tutto si complica!

Come è possibile risolvere questo problema? Seguendo dei semplici passi è possibile simulare un HttpContext, partiamo dai requisiti:

  • Il progetto della nostra web-application: MyWebApplicationExample.
  • Una cartella virtual sul server web IIS che si riferisce alla mia applicazione.
  • Il progetto di test (Libreria di classi) per la web-application: MyWebApplicationExample.Test

Nel nostro progetto di test (che come ho specificato sopra è una Libreria di Classi), dobbiamo aggiungere un riferimento: System.Web.

Successivamente è necessario creare un “Servizio di test”, una classe che esponga gli strumenti necessari per la creazione di un HttpContext valido:

using System;
using System.Web;
using System.Web.Hosting;
namespace MyWebApplicationExample.Test {
    internal static class TestServices {
        internal static void CreateHttpContext {
            TextWriter tw = new StringWriter();
            HttpWorkerRequest wr = new SimpleWorkerRequest(
                  "/MyWebApplicationExample",
                  @"ROOT\PATH\MyWebApplicationExample",
                  "Default.aspx", "", tw);
            HttpContext.Current = new HttpContext(wr);
        }
    }
}

[ad#ad-lungo]

Ora è necessario spiegare alcune cose relativamente all’oggetto HttpWorkerRequest. In ordine di inserimento nel codice sopra, descrivo ogni valore che ho specificato per l’inizializzazione:

  • appVirtualDir (“/MyWebApplicationExample”): è il percorso virtuale (sul server web IIS, per intenderci: http://serveriis/appVirtualDir) dell’applicazione;
  • appPhysicalDir (@”ROOT\PATH\MyWebApplicationExample): è il percorso fisico in cui è posizionato il progetto (es. C:\MyProjects\MyWebApplicationExample);
  • page (“Default.aspx”): indica il percorso virtuale della richiesta, il nostro progetto avrà sicuramente una pagina (altrimenti che web application è?), la utilizziamo per indicare un riferimento diretto (da qui si inizia ad intuire che l’obiettivo è proprio simulare una richiesta ottenendo cosi un HttpContext valido) ad una pagina web della web-application.
  • query (“”): query string della richiesta, è possibile lasciarla anche vuota (es. possiamo utilizzarla per passare dei parametri ottenendo cosi una richiesta del tipo Default.aspx?Param1=value1&etc…).
  • output ( tw ): l’output da utilizzare come contenitore per il nostro WorkerRequest.

In definitiva, quello che ho fatto è configurare un nuovo HttpContext che si riferisce direttamente a quello di un’applicazione attiva (proprio quella di cui ne vogliamo testare alcune caratteristiche) su un server web IIS (è sempre buona cosa testare le web-application utilizzando un server web e non la versione integrata nell’ide, successivamente le soprese potrebbero essere davvero tante e non buone!). L’operazione finale è quella di impostare il contesto Http della libreria stessa su un nuovo HttpContext che utilizza il TextWriter risultante del WorkerRequest. Ora per verificare che quanto scritto funzioni possiamo creare un test (non utilizzo SetUp e TearDown per questioin pratiche in questo esempio).

using System;
using System.Web;
using NUnit.Framework;
namespace MyWebApplicationExample.Test {
    public sealed class TestHttpContextCache {
        public void Test() {
            TestServices.CreateHttpContext();
            Assert.IsNull(HttpContext.Current.Cache["Example"]);
            HttpContext.Current.Cache.Insert("Example", "MyWebApplication");
            Assert.IsNotNull(HttpContext.Current.Cache["Example"]);
            Assert.AreEqual(HttpContext.Current.Cache["Example"].ToString(),
                "MyWebApplication");
        }
    }
}

Se il nostro TestService funziona correttamente, testando questa classe con NUnit dovremmo ottenere una stupendissima linea verde ad indicarci che tutti i test sono stati completati con successo!