SpringRunner和SpringJUnit4ClassRunner的區別及說明

SpringRunner和SpringJUnit4ClassRunner有什麼區別?

@RunWith(SpringRunner.class)
@RunWith(SpringJUnit4ClassRunner.class)

這兩個有什麼區別?

SpringRunner 繼承瞭SpringJUnit4ClassRunner,沒有擴展任何功能;使用前者,名字簡短而已。

SpringRunner無法映射到SpringJUnit4ClassRunner

如果在Maven依賴中可以看到該庫已經載入,必須去掉<scope>test</scope>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

PS:scope的分類

compile(編譯范圍)

  • 默認就是compile,什麼都不配置也就是意味著compile。
  • compile表示被依賴項目需要參與當前項目的編譯,當然後續的測試,運行周期也參與其中,是一個比較強的依賴。
  • 打包的時候通常需要包含進去。

test(測試范圍)

  • scope為test表示依賴項目僅僅參與測試相關的工作,包括測試代碼的編譯,執行。
  • 比較典型的如junit。

runntime(運行時范圍)

  • runntime表示被依賴項目無需參與項目的編譯,不過後期的測試和運行周期需要其參與。與compile相比,跳過編譯而已,說實話在終端的項目(非開源,企業內部系統)中,和compile區別不是很大。
  • 比較常見的如JSR×××的實現,對應的API jar是compile的,具體實現是runtime的,compile隻需要知道接口就足夠瞭。
  • Oracle jdbc驅動架包就是一個很好的例子,一般scope為runntime。
  • 另外runntime的依賴通常和optional搭配使用,optional為true。我可以用A實現,也可以用B實現。

provided(已提供范圍)

  • provided意味著打包的時候可以不用包進去,別的設施(Web Container)會提供。
  • 事實上該依賴理論上可以參與編譯,測試,運行等周期。
  • 相當於compile,但是在打包階段做瞭exclude的動作。
  • 例如, 如果你開發瞭一個web 應用,你可能在編譯 classpath 中需要可用的Servlet API 來編譯一個servlet,但是你不會想要在打包好的WAR 中包含這個Servlet API;這個Servlet API JAR 由你的應用服務器或者servlet 容器提供。
  • 已提供范圍的依賴在編譯classpath (不是運行時)可用。
  • 它們不是傳遞性的,也不會被打包。

system(系統范圍)

  • system范圍依賴與provided 類似,但是你必須顯式的提供一個對於本地系統中JAR 文件的路徑。
  • 這麼做是為瞭允許基於本地對象編譯,而這些對象是系統類庫的一部分。這樣的構件應該是一直可用的,Maven 也不會在倉庫中去尋找它。
  • 如果你將一個依賴范圍設置成系統范圍,你必須同時提供一個 systemPath 元素。
  • 註意該范圍是不推薦使用的(你應該一直盡量去從公共或定制的 Maven 倉庫中引用依賴)。

scope的依賴傳遞

A–>B–>C。當前項目為A,A依賴於B,B依賴於C。知道B在A項目中的scope,那麼怎麼知道C在A中的scope呢?

答案是:

  • 當C是test或者provided時,C直接被丟棄,A不依賴C;
  • 否則A依賴C,C的scope繼承於B的scope。

總結

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: