2016-08-23 104 views
4

最近,我開始對TDD工作exisitng項目面臨幾個問題,其中之一是下面嘲諷/磕碰類的私有變量,而getter和setter方法

我有一個私有變量在被嘲笑提及測試類和可變看起來像下面

private Class<XYZ> cls = XYZ.class; 

後面這種「CLS」變量被用作arugment對於該方法中的一個作爲的className

private List create(Class className, Object objectTO, List<String> names) 

我知道私有變量可以被嘲笑和 我嘲笑了私有變量在我的測試情況下,通過下面的下面的步驟

  1. 宣佈爲java.lang.reflect.Field;
  2. Field field = PowerMockito.field(XYZ.class,"cls");
  3. field.set(XYZ.class, "objectOfXYZClass");

運行我的測試類,我得到低於錯誤

java.lang.IllegalArgumentException: Can not set java.lang.Class field com.tools.XYZ.cls to java.lang.Class 
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) 
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) 
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55) 
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75) 
at java.lang.reflect.Field.set(Field.java:680) 

請有人可以幫我解決這個問題,讓我知道我錯過了什麼。

PS:我用@preparefortest並提到所有在所需的類和使用@runwith(powermockrunner.class)

回答

1
field.set(instanceOfClassXYZ, "") 

放在一組,類的實例上運行我的測試類。不上課。因爲你將字符串「objectOfXYZClass」設置爲一個對象。沒有到類級;) ,我會添加

field.setAccessible(true); 
+0

@ Sarseth..yes that was working for me..my bad,filed .set()我以其他方式做...非常感謝。 –

2

你得到單元測試是錯誤的。它們不是測試內部實現(如字段或私有方法)。

的單元測試通常只能做以下的事情:

  1. 你「下的測試類」
  2. 你調用該對象的公共方法創建的對象;並且你對這些調用的結果「斷言」(這將包括例如在這裏或那裏期望某些例外)。

換句話說:你非常想只有「測試類」您的外部可見行爲測試。而且你知道:如果你的班級沒有外部可見的行爲 - 你爲什麼比在第一位?!

當然,有時候這並不「夠好」。在這種情況下,你通常會這樣做:轉向一些嘲諷框架(如EasyMock或Mockito)來創建嘲笑的對象。你在實例化你的類時使用這些模擬(稱爲依賴注入)。通過這樣做,你可以完全控制你的班級,例如,您可以驗證您的模擬可以看到您期望的那些方法調用。

所以,長話短說:是的,這將有可能以某種方式訪問​​您的課堂的測試領域。但是這導致了不值得這個名字的單元測試。因爲只要開始重構代碼的內部結構,那些測試就會中斷。從這個意義上說:這樣的測試只能證明你當前的實現按預期工作。但是,無論何時你改變某些東西,你都必須重做(可能更大!)部件或測試代碼。

最後:寫單元測試是一項需要學習的技能。最好的資源之一是那些videos