Archive for tag: Unittest

Unittest af database og strengtest med contains

Jeg sad lige med en test der drillede. Det handlede om at jeg lave et opslag i min database med Linq to Sql, hvor kriteriet var noget i stil med 

q = q.Where(v => 
    v.Description.Contains(txt) 
    || v.Title.Contains(txt)
);

I min test testede jeg så på nogenlunde det samme kriterium, dvs. noget i stil med:

Assert.Istrue(
    actual.TrueForAll(v => 
        v.Description.Contains(txt) 
        || v.Title.Contains(txt)
    ));

Men dette fungerede ikke og min test fejlede!? Hm!

Efter noget roden frem og tilbage, kom jeg til at tænke på, at min database jo nok var sat op til at sammenligne strenge uden hensyntagen til forskellen mellem store og små bogstaver, hvilket jo ikke er tilfældet med String.Contains, der ser forskellen. 

Løsningen i min test blev derfor:

Assert.Istrue(
    actual.TrueForAll(v => 
        v.Description.IndexOf(txt, 
            StringComparison.InvariantCultureIgnoreCase) >= 0
        || v.Title.IndexOf(txt, 
            StringComparison.InvariantCultureIgnoreCase) >= 0
    ));

 Så passerer testen igen... :-)

NCrunch til at motivere unittesting

Jeg har for nylig installeret NCrunch i min Visual Studio 2010 og det har været en booster for min lyst til at skrive unittests!

Hvor unittests før var noget jeg skrev, når jeg virkelig havde brug for at teste noget kompleks funktionalitet, er det, efter installationen af NCrunch, blevet motiveret af, at jeg hele tiden kan se, hvilke linjer i koden der ikke er dækket af en test, samt (næsten) øjeblikkeligt får feedback til linjer der indgår i tests der fejler.

NCrunch kører i baggrunden og udfører de tests som findes i den aktuelle solution. Dette gør at jeg kan skrives tests og kode funktionalitet uden at skulle tænke på hele tiden at builde mit projekt for at se om det jeg laver rent faktisk er syntaktisk korrekt og fungerer - det sørger NCrunch, i store træk, for at fortælle mig. Konsekvensen heraf er, at mit tidsforbrug er blevet mindre.

Der er dog nogle ting som er værd at overveje, nemlig at NCrunch i skrivende stund er et (gratis) betaprodukt, men at det givetvis kommer til at koste noget at bruge når det går ud af beta. Det er dog i version 1.38, så noget udvikling er der da foregået på produktet.

Selvom det kommer til at koste noget at bruge, tror jeg nu nok jeg kommer til at købe en licens til det, da det virkelig har ændret min holdning til at skrive unittests. Jeg kan anbefale at give det en chance, hvis du bare interesserer dig lidt for at skrive unittests, men synes det er bøvlet at bruge den indbyggede platform.

Tjek det ud på http://www.ncrunch.net/

 

Ninject med ASP.NET MVC 3

Jeg er for alvor begyndt at bevæge mig ind i .NET-udvikling og er i den forbindelse igang med at lære en masse nye begreber og metoder, som, for mange metoders vedkommende, ikke har givet så meget mening at arbejde ud fra i et ASP Classic miljø (mest fordi miljøet ikke understøtter værktøjerne til at gøre tingene på den måde).

Jeg tænker på områder som

  • SoC (Separation of Concern)
  • DI (Dependency Injection)
  • DRY (Don't Repeat Yourself)
  • Automatiserede tests

m.fl.

Jeg er klar over at man godt kan udøve ovenstående praksiser i ASP Classic (og jeg har da i nogen grad forsøgt dette gennem tiden), men da måden at inkludere kode på er yderst kluntet i mere komplekse scenarier og muligheden for at benytte objektorientering er begrænset, kræver det i bedste fald en yderst disciplineret udvikler at gennemføre dette. Desuden er muligheden for at isolere koden fra IIS begrænsede i ASP og derfor er unittests af kode som benytter session, response, request osv. besværlige i bedste fald.

Begreberne og metoderne er noget lettere at arbejde med i .NET, som i høj grad understøtter disse. Specielt når man arbejder med ASP.NET MVC.

En af de metoder jeg er blevet glad for er DI. DI tvinger mig til at tænke på tingene i mindre og mere afgrænsede opgaver for at få tingene til at hænge ordentlig sammen. DI øger også testbarheden af koden, hvilket understøtter et andet af ovenstående punkter.

DI kan gøres manuelt, men det kan hurtigt blive træls at skulle instantiere objekter alle de steder hvor man skal injicere funktionalitet, så derfor har jeg været på jagt efter et DI-framework, som kunne hjælpe med dette.

Jeg har fundet Ninject. Det eneste DI-framework jeg har prøvet, men jeg fornemmer det skiller sig ud fra mange andre DI-frameworks i.o.m. det ikke konfigureres i en XML-fil og dermed fjerner evt. fejl som følge at tastefejl i den tekstuelle XML. Det er i stedet konfigureret i kode og dermed bliver bindinger testet på compiletidspunktet, hvilket jo giver en tidligere mulighed for at fange evt. fejl. Dermed ikke sagt at det fjerner kørselsfejl ifm. instantiering, men det er en fejlkilde mindre ifht. konfiguration via XML.

Der findes et hav af extensions til Ninject, herunder til webforms, mvc3 og azure. Jeg har ikke selv arbejdet i meget andet end MVC 3 med ninject (ud over et lille testprojekt til webforms), så jeg har ikke den store erfaring med hvordan det fungerer i andre sammenhænge, men mon ikke det mest er et spørgsmål om opsætning. Resten kører nok ens, uanset projektets form, når først DI-frameworket er initialiseret.

Du kan tjekke ninject ud her: www.ninject.com