2016-07-22 138 views
2

目前JUNIT5 API只允許@BeforeAll只對是靜態的方法什麼是科特林爲@BeforeAll適當的解決方法

所以如果要是不喜歡這一點,這不會編譯:

@BeforeAll 
    fun setup() { 
    MockitoAnnotations.initMocks(this) 
    mvc = MockMvcBuilders.standaloneSetup(controller).build() 
} 

所以爲了在科特林靜態方法,我必須把同伴對象是這樣的:

companion object { 
    @JvmStatic 
    @BeforeAll 
    fun setup() { 
     MockitoAnnotations.initMocks(this) 
     mvc = MockMvcBuilders.standaloneSetup(smsController).build() 
    } 
} 

這將編譯,但我沒有從父類訪問的變量。那麼用Kotlin調用JUnit5的@BeforeAll會怎樣呢?

+0

我認爲這是錯誤的,你使用'@ BeforeAll'。你爲什麼不用'@ BeforeEach'? –

+0

我的印象是,JUnit 5只實例化了一次測試類,但它看起來就像它爲每個測試用例做的那樣。 「@ BeforeAll」和「@ BeforeEach」之間沒有任何區別......幾乎沒有區別 –

回答

4

作爲@BeforeAll文檔中所述:

表示該註釋的方法應之前執行的所有@Test 方法在當前類中;類似於JUnit 4的@BeforeClass。 這樣的方法必須是靜態的並且被繼承。

上述對於Kotlin和Java都是如此。請記住,默認情況下,Junit將爲每個測試用例創建一個單獨的測試類實例。因爲它應該在當前測試用例的任何代碼之前被調用,所以@BeforeAll僅適用於靜態方法。靜態方法無法訪問實例成員,因爲可以在沒有實例的情況下調用

由於Spring文檔中所述:

在另一方面,「standaloneSetup」是一個稍微靠近一個單元測試。

的例子顯示,你應該只使用實例成員,像這樣:

class StandaloneTest { 
    val smsController = ... // create instance of controller 
    val MockMvcBuilders.standaloneSetup(smcController).build() 
} 

@BeforeAll的效用是有限的,一般應當避免,因爲它可能鼓勵測試用例之間運行時依賴。

0

JUnit 5有@TestInstance(PER_CLASS)註釋可用於此目的。其中之一,它能使特點是非靜態的BeforeAllAfterAll方法:

@TestInstance(PER_CLASS) 
class BeforeAllTests { 

    lateinit var isInit = false 

    @BeforeAll 
    fun setup() { 
     isInit = true 
    } 

    @TestFactory 
    fun beforeAll() = listOf(
     should("initialize isInit in BeforeAll") { 
      assertTrue(isInit) 
     } 
    ) 
} 

fun should(name: String, test:() -> Unit) = DynamicTest.dynamicTest("should $name", test)