2017-06-05 2 views
0

Ich habe eine Klasse:Wie testet man das private Feld auf den bereitgestellten Wert mit der public-Methode in JUnit?

public class MyEncryptor { 

    private StringEncryptor stringEncryptor; // this is an interface ref 

    public void setStringEncryptor(StringEncryptor stringEncryptorImpl) { 

     if(condition){ 
      this.stringEncryptor = stringEncryptorImpl; 
     } 

    } 
} 

Bei der Prüfung in JUnit für Verfahren setStringEncryptor, ich will stringEncryptor wenn Instanz testen Wert eingestellt ist, was ich in Parameter als Implementierung geliefert haben? oder ich gehe in die falsche Richtung, um diese Methode zu testen?

Unten ist mein gescheiterter Versuch in einer JUnit-Testmethode:

MyEncryptor decryptor = new MyEncryptor(); 

     StringEncryptor spbe = new StandardPBEStringEncryptor(); 
     decryptor.setStringEncryptor(spbe); 

     Field f = MyEncryptor .class.getDeclaredField("stringEncryptor"); 
     f.setAccessible(true); 

     Assert.assertSame(f, spbe); 

Ich mag, dass stringEnctyptor testen gesetzt in junit

+0

Warum möchten Sie den Setter testen?Die wichtigste Regel ist das Testen des Verhaltens. Nehmen Sie beispielsweise an, dass StringEncryptor über eine öffentliche encrypt() -Methode verfügt. Ihr Komponententest sollte bestätigen, dass die Methode encrypt() korrekt verschlüsselt ist. –

+0

Es ist nicht der Setter, es hat mehr Logik im Inneren, ich habe gerade den Code verdünnt, um das Szenario zu simulieren – Ajeetkumar

Antwort

0

Hier behaupten Sie, dass die java.lang.reflect.Field stringEncryptor ist das gleiche Objekt als das StringEncryptor Objekt, das Sie für Ihren Test erstellen:

StringEncryptor spbe = new StandardPBEStringEncryptor(); 
... 
Field f = MyEncryptor .class.getDeclaredField("stringEncryptor"); 
f.setAccessible(true); 
Assert.assertSame(f, spbe); 

Dies sind zwei verschiedene Objekte aus zwei verschiedenen und keine verwandten Klassen .
Sie sollten zunächst den Wert abrufen zu dem Feld zugeordnet:

Object value = f.get(spbe); 

und dann die Objekte vergleichen:

Assert.assertSame(value, spbe); 

Aber trotzdem glaube ich nicht, dass es der gute Weg ist.
Um einen Code zu testen, sollte die Implementierung testbar sein.
Reflexion tun, um den Code zu testen sollte nur getan werden, wenn wir wirklich nicht die Wahl haben.
Eine natürliche Weise, Ihren Code zu prüfen, stellt eine Methode zur Verfügung, um das tatsächliche StringEncryptor Feld zu erhalten.

public StringEncryptor getStringEncryptor(){ 
    return stringEncryptor; 
} 

Auf diese Weise können Sie den Feldwert in einer geraden Art und Weise geltend zu machen.

1

Das Gerät Test, den Sie gegeben spbe haben, schlägt fehl, weil Sie versuchen, Vergleichen Sie eine Field Instanz und eine StandardPBEStringEncryptor Instanz mit assertSame. Was Sie tun sollten, ist: assertSame(f.get(decryptor), StandardPBEStringEncryptor)

Beachten Sie, dass wir die Field::get Methode verwenden, um den Wert des Feldes abzurufen, und das Argument, das wir geben, ist die Instanz, dessen Feldwert wir abrufen möchten.

Unabhängig davon ist die Einheit, die eine Setter-Methode testet, redundant und fügt einfach ohne zusätzlichen Grund zusätzlichen Testcode und Testzeit hinzu.

0

ich möchte testen, ob der instance value stringEncryptor auf was gesetzt ist in Parameter als Implementierung geliefert? oder ich gehe in die falsche Richtung zum Testen dieser Methode?

Ich denke, du gehst in die falsche Richtung. Wo immer es möglich ist, würde ich testen, ob die zu testende Einheit die Verschlüsselung wie erwartet durchführt, nicht speziell, wenn ein privates Feld eingerichtet wird. Sie möchten wirklich die Funktionalität der Einheit testen und nicht die Einzelheiten ihrer Implementierung.

Verwandte Themen