[英]How to test private field is set to supplied value using public method in JUnit?
我有一堂課:
public class MyEncryptor {
private StringEncryptor stringEncryptor; // this is an interface ref
public void setStringEncryptor(StringEncryptor stringEncryptorImpl) {
if(condition){
this.stringEncryptor = stringEncryptorImpl;
}
}
}
在JUnit中測試方法setStringEncryptor
,我想測試實例值stringEncryptor
是否設置為參數中提供的實現? 還是我要以錯誤的方式測試此方法?
以下是我在junit測試方法中的失敗嘗試:
MyEncryptor decryptor = new MyEncryptor ();
StringEncryptor spbe = new StandardPBEStringEncryptor();
decryptor.setStringEncryptor(spbe);
Field f = MyEncryptor .class.getDeclaredField("stringEncryptor");
f.setAccessible(true);
Assert.assertSame(f, spbe);
我想測試將stringEnctyptor
設置為在junit中使用spbe
您提供的單元測試失敗,因為您嘗試使用assertSame
比較Field
實例和StandardPBEStringEncryptor
實例。 您應該做的是: assertSame(f.get(decryptor), StandardPBEStringEncryptor)
請注意,我們使用Field::get
方法檢索字段的值,而我們給出的參數是我們要檢索其字段值的實例。
但是,無論如何,對setter類型方法進行單元測試是多余的,並且無緣無故地簡單地添加了額外的測試代碼和測試時間。
在這里,您斷言java.lang.reflect.Field stringEncryptor
是與您為測試創建的StringEncryptor
對象相同的對象:
StringEncryptor spbe = new StandardPBEStringEncryptor();
...
Field f = MyEncryptor .class.getDeclaredField("stringEncryptor");
f.setAccessible(true);
Assert.assertSame(f, spbe);
這是兩個不同且沒有相關類的兩個不同對象。
您應該首先檢索與該字段關聯的值:
Object value = f.get(spbe);
然后比較對象:
Assert.assertSame(value, spbe);
但是無論如何,我都不認為這是個好方法。
要測試代碼,實現應是可測試的。
只有在我們真的沒有選擇的情況下,才應該進行反射測試代碼。
測試代碼的自然方法是提供一種獲取實際StringEncryptor
字段的方法。
public StringEncryptor getStringEncryptor(){
return stringEncryptor;
}
這樣,您可以直接聲明字段值。
我想測試實例值stringEncryptor是否設置為我在實現中的參數中提供的值? 還是我要以錯誤的方式測試此方法?
我認為您走錯了路。 只要有可能,我都會測試被測單元是否按預期進行了加密,而不是專門設置了私有字段。 您確實要測試單元功能,而不是測試其實現的細節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.