2010-05-13 27 views
58

是否有任何最佳實踐來讓Junit在測試文件中執行一次函數,並且它也不應該是靜態的。Junit課前(非靜態)

like @BeforeClass on non static function?

這裏是一個醜陋的解決方案:

@Before void init(){ 
    if (init.get() == false){ 
     init.set(true); 
     // do once block 
    } 
} 

好這是我不想做的,我期待爲一體的綜合解決方案的JUnit。

+0

出於興趣你爲什麼試圖做到這一點? – Goibniu 2010-05-13 09:35:46

+0

那麼,我有一個相當大的測試文件和基礎測試文件的層次結構,我需要在子測試類中覆蓋此操作的可能性。 – Roman 2010-05-13 09:39:29

+1

我有同樣的問題,其中只有許多參數化測試中的第一個應該執行登錄。 – dokaspar 2012-10-05 14:27:57

回答

14

如果你不想設置靜態初始化一次性初始化,並不是特別關注使用JUnit,請看看TestNG。 TestNG支持使用各種配置選項進行非靜態,一次性初始化,全部使用註釋。

TestNG中,這將相當於:

@org.testng.annotations.BeforeClass 
public void setUpOnce() { 
    // One time initialization. 
} 

對於拆機,

@org.testng.annotations.AfterClass 
public void tearDownOnce() { 
    // One time tear down. 
} 

對於TestNG的相當於JUnit 4的@Before@After的,可以分別使用@BeforeMethod@AfterMethod

0

我從來沒有嘗試過,但也許你可以創建一個無參數構造函數並從那裏調用你的函數?

+0

這會奏效,問題是我需要在擴展此基本測試類的類中覆蓋此操作的可能性 – Roman 2010-05-13 09:38:20

+0

@Roman:哦,現在我明白了。將此添加到您的帖子中,此評論使事情變得更清晰。 – Roman 2010-05-13 09:57:51

+0

構造函數將被多次調用測試用例。對於每個測試方法,都將創建新的Test類對象。所以,使用構造函數不是這裏的解決方案 – manikanta 2011-09-27 18:46:27

31

使用空的構造函數是最簡單的解決方案。您仍然可以覆蓋擴展類中的構造函數。

但是對於所有的繼承來說它並不是最優的。這就是爲什麼JUnit 4使用註釋代替。

另一種選擇是在factory/util類中創建一個輔助方法,並讓該方法完成工作。

如果您使用的是Spring,則應考慮使用@TestExecutionListeners註釋。 事情是這樣的測試:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({CustomTestExecutionListener.class, 
    DependencyInjectionTestExecutionListener.class}) 
@ContextConfiguration("test-config.xml") 
public class DemoTest { 

Spring的AbstractTestExecutionListener例如包含您可以覆蓋這個空方法:

public void beforeTestClass(TestContext testContext) throws Exception { 
    /* no-op */ 
} 
+0

+1這個技巧解決了我想要使用DbUnit時的問題,並且每個類只加載一次數據集 – Brad 2011-11-29 12:16:06

+0

+1對於那些沒有被綁定到Spring的古老版本的人來說,這是完美的...。 :( – 2012-03-22 18:28:57

+0

這個'beforeTestClass()'會在上下文初始化之前或之後調用嗎? – Dims 2015-10-06 19:21:19

28

一個簡單的if語句似乎工作得也很好:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:test-context.xml"}) 
public class myTest { 

    public static boolean dbInit = false; 

    @Autowired 
    DbUtils dbUtils; 

    @Before 
    public void setUp(){ 

     if(!dbInit){ 

      dbUtils.dropTables(); 
      dbUtils.createTables(); 
      dbInit = true; 

     } 
    } 

... 
+1

好而簡單!但是看不到一種方法來簡單地調整它以創建非靜態的'@ AfterClass'等價物,測試已經運行? – 2015-06-27 07:16:38

+0

請參閱[這裏](http:// stackoverflow。com/questions/12087959/junit-run-set-up-method-once/31117171#31117171),該方法的更新應該適用於使用繼承的測試類。 – 2015-06-30 09:59:03

-1

更新:請看到櫻桃爲什麼下面的建議是有缺陷的評論。(上午離開答案原樣,而不是刪除/編輯作爲註釋,可以提供有用的信息給別人,爲什麼這是行不通的。)


另一個值得考慮的選擇,如果使用依賴注入(如Spring)是@PostConstruct。這將保證依賴注入完成後,這將不會是在構造函數的情況:

@PostConstruct 
public void init() { 
    // One-time initialization... 
} 
+6

在Junit測試的情況下,**非常糟**。 Junit每次運行測試方法時創建測試類實例。所以如果在類中有6個測試方法,一個類構造函數'@ Before'和'@ After'方法將被調用6次!所以在這種情況下'@ PostConstruct'的行爲就像'@ Before'註釋。你可以簡單地測試它:只要在測試類中添加2個測試方法,添加'@PostConstruct public void init(){System.out.println(「started」);}'並在日誌中查看它打印多少次。 – Cherry 2014-10-01 06:02:56

+0

有關信息,我剛剛遇到[JUnit文檔](http://junit.sourceforge.net/javadoc/org/junit/Test.html),它確認了上面有關JUnit爲每個「@」創建實例的註釋中描述的內容。測試運行:*「爲了運行該方法,JUnit首先構造一個新的類實例,然後調用註釋的方法。」* – 2017-09-14 15:01:31

0

The article討論這個問題2個很不錯的解決方案:

  1. 「乾淨」的junit用自定義的Runner(使用接口,但你可以用一個自定義註釋來擴展它,例如@BeforeInstance)
  2. Espen之前提到的Spring執行偵聽器。
-1

只需使用@BeforeClass

@BeforeClass 
public static void init() { 
} 

它沒有意義,因爲每個測試是在一個單獨的實例中運行init是非靜態的。運行init的實例 與任何測試的實例都不匹配。

您可能希望它是非靜態的唯一原因是在子類中覆蓋它,但是您也可以使用靜態方法執行此操作 。只需使用相同的名稱,並且只會調用子類init方法。

+0

這整個問題是關於以非靜態方式執行它的可能性,如果需要你需要一些類的實例變量。 – 2017-02-02 09:11:34

+0

@SimonForsberg是的,我說這個問題是一個XY問題。該操作說,這個問題正在壓倒兒童班的行爲。如果這個例子需要實例變量,那麼我可能會建議其他的東西。 – fgb 2017-02-02 13:48:21

+0

看到這個評論:http://stackoverflow.com/questions/2825615/junit-before-class-non-static/27730780?noredirect=1#comment2866266_2825615 – 2017-02-02 16:45:13

4

很容易使用@BeforeAllMethods/@AfterAllMethods批註在實例上下文(非靜態)內運行一個方法,其中所有注入的值都將可用。

有這個特殊的測試庫:

https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0

https://bitbucket.org/radistao/before-after-spring-test-runner/

唯一的限制:只適用測試。

(我是這個測試庫的開發者)

+0

請讓我知道你是否要使用圖書館 - 我想獲得一些用戶體驗,以瞭解這個項目是否對社區有意義。謝謝 – radistao 2017-12-21 11:10:15