標籤:style blog http color java 使用 os io
類比泛型
Java的泛型系統不能夠和它的動態反射API很好的工作.對於jMock,這意味著當你類比泛型時編譯器會警告你可能靜態類型錯誤.警告是不正確的.避免它們最好的方法是在類比對象聲明的變數上使用一個注釋抑制警告.
例如,下列泛型介面:
public interface Juicer<T extends Fruit> { Liquid juice(T fruit);}
在一個測試中,你需要類比這個介面,如下:
Juicer<Orange> orangeJuicer = context.mock(Juicer<Orange>.class, "orangeJuicer");Juicer<Coconut> coconutJuicer = context.mock(Juicer<Coconut>.class, "coconutJuicer");
然而,依照java文法結構這是不正確的.你實際必須寫成下列內容:
Juicer<Orange> orangeJuicer = (Juicer<Orange>)context.mock(Juicer.class, "orangeJuicer");Juicer<Coconut> coconutJuicer = (Juicer<Coconut>)context.mock(Juicer.class, "coconutJuicer");
那些行,雖然在語句結構和語義上都是正確的,但是產生了安全警告.為了避免這些警告,你必須使用@SuppressWarnings注釋變數聲明:
@SuppressWarnings("unchecked")Juicer<Orange> orangeJuicer = context.mock(Juicer.class, "orangeJuicer"); @SuppressWarnings("unchecked")Juicer<Coconut> coconutJuicer = context.mock(Juicer.class, "coconutJuicer");
希望Java未來版本會提高泛型系統使這不是必須的.
使用jMock和ClassImposteriser類比類
因為jMock使用Java的預設反射能力,所以jMock架構的預設配置僅僅可以類比介面,不能類比類.(事實上,我們考慮那對於我們來說是件好事,因為它鼓勵設計聚焦在對象之間的通訊,而不是靜態分類和資料存放區.)然而ClassImposteriser擴充類使用CGLIB2.1和Objenesis類庫來像介面一樣建立類的類比對象.當使用遺留代碼工作時對於分解緊耦合類之間的依賴關係是很有用的.
ClassImposteriser建立類比執行個體不需要調用類比類的建構函式.所以帶有有參數或調用可覆蓋的對象方法的建構函式的類可以被安全的類比.然而ClassImposteriser不能建立最終類或最終方法的類比.
如果你想類比最終類或者最終方法,JDave類庫包含了一個反最終(unfinalizer)代理裝置,它在JVM載入它們前能夠使類變為非最終的. 它們然後就可以通過ClassImposteriser類比.
來使用ClassImposteriser:
1. 添加jmock-legacy-2.5.1.jar, cglib-nodep-2.1_3.jar 和 objenesis-1.0.jar到你的CLASSPATH.
2. 匯入ClassImposterise到你測試類別r into the Mockery of your test class:
1 JUnit 3 2 3 import org.jmock.Expectations; 4 import org.jmock.integration.junit3.MockObjectTestCase; 5 import org.jmock.lib.legacy.ClassImposteriser; 6 7 public class ConcreteClassTest extends MockObjectTestCase { 8 { 9 setImposteriser(ClassImposteriser.INSTANCE);10 }11 12 ...13 }14 JUnit 415 16 import org.jmock.Mockery;17 import org.jmock.Expectations;18 import org.jmock.integration.junit4.JUnit4Mockery;19 import org.jmock.lib.legacy.ClassImposteriser;20 21 @RunWith(JMock.class)22 public class ConcreteClassTest {23 private Mockery context = new JUnit4Mockery() {{24 setImposteriser(ClassImposteriser.INSTANCE);25 }};26 27 ...28 }29 Other30 31 import org.jmock.Mockery;32 import org.jmock.Expectations;33 import org.jmock.lib.legacy.ClassImposteriser;34 35 public class ConcreteClassTest extends TestCase {36 private Mockery context = new Mockery() {{37 setImposteriser(ClassImposteriser.INSTANCE);38 }};39 40 ...41 }
3.你的測試現在可以建立抽象的或者甚至具體的類的類比了:
Graphics g = context.mock(java.awt.Graphics.class);