我在JUnit中有很多測試用例。它們都需要使用相同的代碼才能在其@BeforeClass
靜態方法中執行。這是一個代碼重複,我試圖擺脫它。這樣做的一個骯髒的方式是繼承。 JUnit中是否有其他機制,可能有所幫助?如何避免JUnit測試用例中的繼承?
PS。我寫了這篇關於這個主題的博客文章:http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html
我在JUnit中有很多測試用例。它們都需要使用相同的代碼才能在其@BeforeClass
靜態方法中執行。這是一個代碼重複,我試圖擺脫它。這樣做的一個骯髒的方式是繼承。 JUnit中是否有其他機制,可能有所幫助?如何避免JUnit測試用例中的繼承?
PS。我寫了這篇關於這個主題的博客文章:http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html
JUnit組成可重用代碼(而不是從中繼承)的方式是規則。
見https://github.com/junit-team/junit/wiki/Rules
這是一個愚蠢的樣品,但你會得到點。
import org.junit.rules.TestRule;
import org.junit.runners.model.Statement;
import org.junit.runner.Description;
public class MyTestRule implements TestRule {
@Override
public Statement apply(final Statement statement, Description description) {
return new Statement() {
public void evaluate() throws Throwable {
// Here is BEFORE_CODE
try {
statement.evaluate();
} finally {
// Here is AFTER_CODE
}
}
};
}
}
然後,您可以使用您的TestRule這樣的:
import org.junit.Rule;
public class MyTest {
@Rule
public MyTestRule myRule = new MyTestRule();
}
BEFORE_CODE和AFTER_CODE然後將圍繞每個測試方法執行。
如果你需要爲每個班級只運行一次你的代碼,用你的TestRule作爲@ClassRule:
import org.junit.ClassRule;
public class MyTest {
@ClassRule
public static MyTestRule myRule = new MyTestRule();
}
現在,BEFORE_CODE
和AFTER_CODE
將圍繞每個測試類的執行。
@Rule字段不是靜態的,@ClassRule字段是。
@ClassRule也可以在套件中聲明。
請注意,您可以在單個測試類中聲明多個規則,這就是如何在測試套件,測試類和測試方法級別組成測試生命週期的方式。
規則是你在你的測試類中實例化的對象(靜態或不靜態)。如果需要,你可以添加構造器參數。
HTH
如果方法是某種實用工具,那麼使用靜態方法將其分離出來,並在@BeforeClass中調用該方法。
我強調這樣一個事實,即不要僅僅因爲它解決了你的問題而使用繼承,而是在你的類層次結構中使用它。
如果每個類都需要有一個@BeforeClass
標註的方法是正是一樣每隔,然後繼承不覺得是我錯了。如果這些初始化方法中的每一個都簡單地共享代碼,則可以使用某種共享行爲創建一個TestUtil
類,並調用每個@BeforeClass
方法的此共享行爲。
靜態方法不會被繼承,因此默認情況下繼承不是一個選項。如果你的意思是你將方法移動到一個共同的父類,那麼這看起來是一個糟糕的選擇,因爲你只能得到一個父Java。某種測試支持類似乎更合適。您也可能看到需要parameterized test。
我認爲如果這些類有「is-a」的關係,繼承是合理的。
如果基類是MyBeforeClass
定義@BeforeClass
方法,和MyTestClass1
「是一個」 MyBeforeClass
,MyTestClass1 extends MyBeforeClass
是OK。
根據設置代碼的性質,您可以將所有測試放在測試suite中,並讓設置代碼在那裏運行。缺點是你不能單獨運行測試(因爲測試取決於設置代碼)。
在這種情況下,繼承沒有任何問題,它實際上是避免在每個子類中重複此代碼的唯一方法。 @BeforeClass方法必須在JUnit中聲明爲靜態的事實是不幸的,但這不應該阻止你。擴展該類,並且您可以自動運行初始化代碼,而無需執行任何操作。
不,它不是唯一的方法,看到其他答案,並且由於靜態方法不被繼承,它是否是一種方式是可疑的。你試過了嗎? – EJP
您可以創建測試運行
public class MyTestRunner extends BlockJUnit4ClassRunner {
@Override
protected Object createTest() throws Exception {
Object test = super.createTest();
doStuff();
}
public void doStuff(){
//common code
}
}
@RunWith(MyTestRunner.class)
public class MyTest1{
@Test
public void test1(){
//test method
}
}
這是測試代碼,這並不意味着對重型再利用。不要過度設計。不要應用你所知道的所有設計模式。對於測試代碼,規則是不同的。
所有'@ BeforeClasses'完全相同還是隻是共享一些代碼? –
爲什麼繼承是一種骯髒的方式? –
@lu,該方法是靜態的,繼承不會是最好的。 –