kyllä, tämä on miljoonakysymys. Miten testata yksityisiä menetelmiä?
pitäisikö kehittäjän testata yksityisiä menetelmiä koodebaasissaan? tai se, että ne jätetään julkisten menetelmien varaan, on keino. Jokaisella kehittäjällä on oma mielipiteensä, että pitäisikö niitä oikeasti testata vai ei. Joten, pähkinänkuoressa, kysymys sai pelkistetty on ” onko olemassa mitään hyvää lähestymistapaa voimme kokeilla tätä työtä?”
niin, tässä ovat kaikki mahdolliset vaihtoehdot kehittäjän testata yksityisiä menetelmiä hänen Java / kotlin-pohjainen Sovellukset 2019:
- älä testaa yksityisiä menetelmiä 😜(ei juuria, ei hapanta rypälettä)
- Anna metodeille julkinen pääsy 😒 (Ei, En tee tätä se on koodauskäytäntöjä vastaan. Olen hyvä Kehittäjä, noudatan parhaita käytäntöjä)
- käytä sisäkkäistä testiluokkaa 😒 (tämä ei ole hyvä sekoittaa tuotantokoodia testikoodiin. Tarvitseeko minun vielä mainita, että olen hyvä kehittäjä ja noudatan vain parhaita käytäntöjä)
- käytä Java Reflection 😃(Kyllä, Tämä näyttää mielenkiintoiselta olen sitä varten)
huolimatta yleisestä uskomuksesta, että on todella mahdollista päästä muiden luokkien yksityisiin kenttiin ja menetelmiin Java Reflection-palvelun kautta. Se ei ole edes niin vaikeaa. Tämä voi olla erittäin kätevä laitteen testauksen aikana.
huomautus: Tämä toimii vain ajettaessa koodia itsenäisenä Java-sovelluksena, kuten yksikkötesteissä ja tavallisissa sovelluksissa. Jos yrität tehdä tämän Java-sovelman sisällä, sinun täytyy näpelöidä Securitymanagerin kanssa. Mutta koska näin ei tarvitse tehdä kovin usein, se on jätetty pois tästä tekstistä toistaiseksi.
Method Parameter Reflection-tuki lisättiin Java 8: aan. Yksinkertaisesti sanottuna, se tarjoaa tukea saada nimet parametrit runtime.
päästäkseen yksityiskenttään on soitettava Class.getDeclaredField(String name)
tai Class.getDeclaredFields()
metodi. Menetelmät Class.getField(String name)
ja Class.getFields()
menetelmät palauttavat vain julkisia kenttiä, joten ne eivät toimi. Tässä on yksinkertainen esimerkki luokasta, jossa on yksityinen kenttä, ja alla koodi, jolla kyseiseen kenttään pääsee Java-heijastuksen kautta:
public class PrivateObject {private String privateString = null;public PrivateObject(String privateString) {
this.privateString = privateString;
}
}PrivateObject privateObject = new PrivateObject("The Private Value");Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");privateStringField.setAccessible(true);String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
tämä koodiesimerkki tulostaa tekstin "fieldValue = The Private Value”
, joka on yksityisen kentän arvo privateString
PrivateObject
koodinäytteen alussa luotu esiintymä.
huomaa menetelmän käyttö PrivateObject.class.getDeclaredField("privateString")
. Se on tämä menetelmä puhelu, joka palauttaa yksityisen kentän. Tällä menetelmällä palautetaan vain kyseisessä luokassa ilmoitetut kentät, ei missään superluokassa ilmoitettuja kenttiä.
huomaa rivi myös lihavoituna. Soittamalla Field.setAcessible(true)
sammutat tämän nimenomaisen Field
esiintymän pääsytarkistukset vain harkintaa varten. Nyt voit käyttää sitä, vaikka se olisi yksityinen, suojattu tai paketti soveltamisala, vaikka soittaja ei kuulu niihin scopes. Kentälle ei edelleenkään pääse normaalilla koodilla. Kääntäjä ei salli sitä.
pääsy yksityisiin menetelmiin
päästäksesi yksityiseen menetelmään sinun täytyy soittaa Class.getDeclaredMethod(String name, Class parameterTypes)
tai Class.getDeclaredMethods()
menetelmä. Menetelmät Class.getMethod(String name, Class parameterTypes)
ja Class.getMethods()
menetelmät palauttavat vain julkisia menetelmiä, joten ne eivät toimi.
tässä on yksinkertainen esimerkki luokasta, jossa on yksityinen menetelmä, ja alla koodi, jolla pääsee kyseiseen menetelmään Java Reflection-sovelluksen kautta:
public class PrivateObject {private String privateString = null;public PrivateObject(String privateString) {
this.privateString = privateString;
}private String getPrivateString(){
return this.privateString;
}
}PrivateObject privateObject = new PrivateObject("The Private Value");Method privateStringMethod = PrivateObject.class.
getDeclaredMethod("getPrivateString", null);privateStringMethod.setAccessible(true);String returnValue = (String)
privateStringMethod.invoke(privateObject, null);System.out.println("returnValue = " + returnValue);
tämä koodiesimerkki tulostaa tekstin "returnValue = The Private Value”
, joka on menetelmällä getPrivateString()
vedottaessa PrivateObject
koodinäyte.
huomaa menetelmän käyttö PrivateObject.class.getDeclaredMethod("privateString")
. Se on tämä menetelmä puhelu, joka palauttaa yksityisen menetelmän. Tämä menetelmä palauttaa ainoastaan kyseiseen luokkaan ilmoitetut menetelmät, ei mihinkään superluokkaan ilmoitetut menetelmät.
huomaa rivi myös lihavoituna. Soittamalla Method.setAcessible(true)
sammutat tämän nimenomaisen Method
esiintymän pääsytarkistukset vain pohdintaa varten. Nyt voit käyttää sitä, vaikka se olisi yksityinen, suojattu tai paketti soveltamisala, vaikka soittaja ei kuulu niihin scopes. Et vieläkään voi käyttää menetelmää normaalilla koodilla. Kääntäjä ei salli sitä.
kokeillaan tätä tietoa johonkin tuotantotason koodiin.
tässä on luokka, joka sisältää joitakin yksityisiä menetelmiä, joita haluamme testata.