Testvenlig VBScript-kode med funktionsstubbe

Hvis man påtænker at teste sin kode kan det være en god idé at fjerne eller minimere afhængighederne mellem de forskellige funktioner i programmet så meget som muligt. Til dette formål kan man bla. benytte VBScript-funktionen GetRef.

Betragt følgende eksempel:

function genererTilfaeldigKode()
  dim tegn, tmp
  tegn = "abcdefghijklmnopqrstuvwxyz"
  tmp = ""
  randomize
  for i=1 to 10
    tmp = tmp & mid(tegn, int(rnd*len(tegn))+1,1)
  next
  genererTilfaeldigKode = tmp
end function

function brugTilfaeldigKode()
  brugTilfaeldigKode = "noget tekst og en kode " & genererTilfaeldigKode()
end function

Eksemplet er naturligvis ret konstrueret, men jeg vil holde det simpelt for at bevare gennemskueligheden af det jeg vil demonstrere.

Det er forhåbentlig oplagt hvad der sker, så jeg vil skynde mig videre med at beskrive udfordringerne med at teste funktionen brugTilfaeldigKode.

Udfordringerne

Funktionen brugTilfaeldigKode benytter sig af funktionen genererTilfaeldigKode, der igen returnerer en tilfældigt genereret 10 tegn lang streng. Det faktum at returværdien af genererTilfaeldigKode er tilfældig, besværliggør test af brugTilfaeldigKode, da man, i sagens natur, aldrig kan være sikker på, hvilken værdi der returneres. Hvis vi skal isolere testen af brugTilfaeldigKode, skal resultatet af kaldene til de funktioner denne funktion foretager være forudsigelige. Dette kan opnås ved at stubbe de funktioner der kaldes fra den testede funktion.

Løsningen

Som nævnt kan man stubbe funktionen genererTilfaeldigKode, således resultatet af denne funktion bliver forudsigeligt i testsituationen. Dette gøres med GetRef og lidt forberedelse af koden. Et eksempel kunne se således ud:

dim genererTilfaeldigKode
set genererTilfaeldigKode = GetRef("fnGenererTilfaeldigKode")

function fnGenererTilfaeldigKode()
  dim tegn, tmp
  tegn = "abcdefghijklmnopqrstuvwxyz"
  tmp = ""
  randomize
  for i=1 to 10
    tmp = tmp & mid(tegn, int(rnd*len(tegn))+1,1)
  next
  fnGenererTilfaeldigKode = tmp
end function

function brugTilfaeldigKode()
  brugTilfaeldigKode = "noget tekst og en kode " & genererTilfaeldigKode()
end function

Nu er koden forberedt på at blive testet. Bemærk at jeg ændrede navnet på selve funktionen til fnGenererTilfaeldigKode i stedet for det oprindelige navn. Dette er gjort for at bevare kompatibiliteten med eksisterende kode som benytter funktionen, dvs. jeg behøver ikke rette alle de potentielt mange steder funktionen genererTilfaeldigKode bliver kaldt og de vil stadig fungere efter denne rettelse.

Testen af brugTilfaeldigKode

Nu er vi klar til at prøve at lave en test af funktionen brugTilfaeldigKode. Det kunne se nogenlunde således ud:

function testTilfaeldigKode()
  testTilfaeldigKode = "abcdefghij"
end function

function testBrugTilfaeldigKode()
  dim exp, act
  set genererTilfaeldigKode = GetRef("testTilfaeldigKode")

  exp = "noget tekst og en kode abcdefghij"
  act = brugTilfaeldigKode()

  if act = exp then
    response.write "Test OK"
  else
    response.write "Test fejlede! Værdien er ikke som forventet."
  end if
end function

Først definerer jeg en stubfunktion som returnerer en kendt kode. Derefter sætter jeg funktionspegepinden genererTilfaeldigKode til at pege på min testfunktion testTilfaeldigKode i stedet for den oprindelige funktion. Nu kan jeg kalde brugTilfaeldigKode i test-funktionen og få et kendt resultat tilbage, som jeg til sidst sammenligner med det forventede resultat.

Konklusion

Ovenstående eksempel var ultrasimpel og totalt konstrueret, men princippet med at stubbe funktioner er ikke desto mindre anvendeligt i et miljø, hvor der er fokus på at unitteste funktioner.

Hvis man skal lave noget seriøs test, er det nok nødvendigt med et mere veludviklet testframework, men det hører til i en hel artikelserie at beskrive, hvordan man smækker sådan et sammen (måske noget der kommer her på sitet senere).

 
Sidst opdateret: 16-09-2010 22:18:20
Tilmeld link | Tilføj Link | Tilføj Link | @-begynder
Erklæring om beskyttelse af personlige oplysninger

nope.dk - Danmarks Website Chart