mboost-dp1

C#, TDD og access level


Gå til bund
Gravatar #1 - Jonasee
10. dec. 2008 08:41
Hej

Så vidt jeg har læret end til nu så skal man sætte så lave et access level på klasser som det er muligt, så langt så godt, men vis man så skal brug TDD og laver et seperat testprojeckt, så kan man, så vidt jeg kan finde ud af, ikke til gå en klasse men mindre den er public. kan det virkelig være meningen at man skal bygge sit test projeckt og det man vil teste samme for det virker forket i mit hoved og det virker heller ikke være rigtig at hele ens proejckt skal være public for at man kan teste det.

Mit spørgsmål er om der er man skal bygge det samme til et projeckt eller skal alt være public eller er der en anden måde at gøre det på?

På forhånd Tak
Jonas
Gravatar #2 - zin
10. dec. 2008 19:57
Hvis du benytter VS kan du ligge det hele ind i samme solution (andet projekt!), men der skal du så huske at oprette en reference til dit andet projekt (kig i solution explorer, her er der en mappe kaldet "references") og huske at referere til projektet som
"using <projektnavnher>.<namespaceher>;".
Idéen i det hele er at man skal have et "tilgangslag" som henter noget data ned i nogle klasser, som man så kan få givet adgang til en liste over. KUN de klasser man skal have adgang til skal være public. Alt andet bør (i princippet) være private.
Gravatar #3 - Jonasee
10. dec. 2008 20:10
#2

Har det skæm i samme solution og men reference, det var at jeg har et projeckt hvor jeg bruger en controller til at styre det hele, så har kun 3 methoder der er public (prepar, update, end), men en hele dele andre methoder jeg gerne vil som jeg gerne vil teste.
Gravatar #4 - arne_v
10. dec. 2008 22:13
#1

Først om fremmest skal du overveje om hvorvidt du overhovedet vil unit teste de ikke accessible metoder.

Dit projekt exposer et givet interface. Dine unit tests tester om hvorvidt din implementation af det interface virker. Hvis du skifter implementation uden at skifte interface kører du de samme unit tests uændret.

I de fleste tilfælde bør din applikation være struktureret sådan at du ikke har behov for at teste ikke accessible metoder.

Har du af en eller anden mystisk grund et reelt behov, så skal du igang med nogle workarounds.

Typiske workarounds er:
1) brug ef reflection
2) selektiv grant af access udover generel accessibility
3) link/include/copy rigtig kode ind i test kode

#2 i .NET verdenen består bl.a. af InternalsVisibleTo attributten.

Ingen af workarounds'ene er super pæne.
Gravatar #5 - Jonasee
10. dec. 2008 22:54
#4

jeg kan godt følg dig i det. det skal jeg huske, tak for hjælpen.
Gravatar #6 - photonatic
20. dec. 2008 18:32
Det er muligt at teste private felter og metoder i NUnit vha reflektion. Eksempel på dette: http://www.jroller.com/CoBraLorD/date/20040901

Det skal naturligvis være muligt at teste private felter og metoder i testfasen, de kan også være kilde til fejl.

I de fleste tilfælde bør din applikation være struktureret sådan at du ikke har behov for at teste ikke accessible metoder.


Man kan da have ønsket at refaktorere en klasse internt, men metoden ønskes ikke eksponeret for omverdenen.

Det er en diskussion om man skal betragte brugen af NUnit udelukkende til black-box test, hvor man kun tester de offentlige felter og metoder, men hvorfor ikke udnytte den fulde viden man har til sin egen kode? Det fede ved unit-testing er jo bl.a., at man kan refaktorere, som man lyster, samtidig med at man tester for at funktionaliteten er det samme - hele tiden. :-)
Gravatar #7 - markjensen
20. dec. 2008 21:57
#6 Ikke at det er specielt vigtigt, men er det ikke det man kalder gray box (og ikke black box). Som jeg har forstået det, tester man public klasser i gray box, hvor man i black box tester systemet helt ude fra (altså fra brugerens synspunkt).

(baseret på hvad jeg har lært i objektorienteret programmering i java)
Gravatar #8 - photonatic
20. dec. 2008 22:23
#7: Du gjorde mig nysgerrig på begrebet "gray box testing". Som jeg tolker det fra Wikipedia, vedrører "black box" test af de offentlige felter og metoder, "white box" af de mulige veje som programmet kan føres hen til (test af samtlige branches af switch, if-statements, etc).

Så er der "gray box", som min tidligere forklaring måske ligger kategoriseret som, idet man har adgang til den interne struktur, men man tester stadig efter "black box"-tankegangen. Men jeg mener ikke, at det er test fra "brugerens synspunkt", det må være en usability test?
Gravatar #9 - arne_v
20. dec. 2008 23:51
photonatic (6) skrev:

Det skal naturligvis være muligt at teste private felter og metoder i testfasen, de kan også være kilde til fejl.


photonatic (6) skrev:

Man kan da have ønsket at refaktorere en klasse internt, men metoden ønskes ikke eksponeret for omverdenen.


Hvis ikke de private members bruges af de public members, så er det et spørgsmål om hvorvidt de overhovedet skal være der.

Hvis de private members bruges af de public members, så bør unit test af de public members også fange fejl i de private members.

Hvis klassen er så kompleks at en fejl i unit test af et public member ikke er nem at relatere til en fejl i en private member, så er det sandsynligvis på tide at få den klasse splittet op.

photonatic (6) skrev:

Det fede ved unit-testing er jo bl.a., at man kan refaktorere, som man lyster, samtidig med at man tester for at funktionaliteten er det samme - hele tiden.


Netop.

Man unit tester for om klassen leverer den funktionalitet udadtil som den skal. Så kan man omstrukturere frit internt og teste om alt er OK *uden* at ændre sine unit tests. At fjerne, tilføje og omdøbe interne metoder er en vigtig del af refaktorering. Det giver en meget grim lugt, hvis eksisterende unit tests skal ændres p.g.a. en refaktorering. Men hvis man unit tester på interne metoder, så må man enten nøjes med at refaktorere indenfor de givne metoder eller lave om på sine unit tests.

Gravatar #10 - arne_v
20. dec. 2008 23:52
Der kan naturligvis være situationer, hvor man har et behov for det, men det er 1 ud af 100 gange.
Gravatar #11 - photonatic
21. dec. 2008 01:38
Puha, er man oppe mod én af de store, erfarne programmeringsguruer*? Men jeg skal forsøge. :-)

Hvis de private members bruges af de public members, så bør unit test af de public members også fange fejl i de private members.


Jeg kan huske en opgave fra første år, hvor vi skulle anvende A*-algoritmen til søgning i en graf. Én af ingredienserne i algoritmen er beregning af den euklidiske afstand, og vi gjorde getEuclideanDistance() privat. Men vi ønskede samtidig at isolere ydelsestesten af A* og beregning af den euklidiske afstand, udover at lave boundary test på inputværdierne. Så vi var i den 1/100 sandsynlighed, hvor vi havde behov for test af den private metode alene. I retrospekt kan det måske have været gjort anderledes.

Men jo, jeg tænkte efter at have sendt beskeden, at det er i hvert fald ikke refaktorering, som bør lægge til grund for at unit-teste private metoder.

* Givet det er dig fra eksperten.dk
Gravatar #12 - arne_v
21. dec. 2008 02:40
#11

Jeg bruger ihvertfald samme brugernavn på eksperten.dk og her.

Med performance test er man lidt udover traditionel unit test.

Men den andel del er en mulig begrundelse, hvis det er svært at ramme de kritiske input værdier i en private metode gennem de public metoder, så kan det godt give mening at at ville unit teste den private metode.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login