簡體   English   中英

如何在JUnit中使用public方法將私有字段測試為提供的值?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM