天天看點

《Spring 5官方文檔》11內建測試 (二)

11.3 jdbc測試支援

org.springframework.test.jdbc是包含jdbctestutils的包,它是一個jdbc相關的工具方法集,意在簡化标準資料庫測試場景。特别地,jdbctestutils提供以下靜态工具方法:

countrowsintable(..):統計給定表的行數。

countrowsintablewhere(..):使用提供的where語句進行篩選統計給定表的行數。

deletefromtables(..):删除特定表的全部資料。

deletefromtablewhere(..):使用提供的where語句進行篩選并删除給定表的資料。

droptables(..):删除指定的表。

spring-jdbc子產品提供了配置和啟動嵌入式資料庫的支援,可用于與資料庫互動的內建測試中。

詳見section 15.8, “嵌入式資料庫支援”和 ection 15.8.5, “使用嵌入式資料庫測試資料通路邏輯”。

11.4 注解

11.4.1 spring測試注解

spring架構提供以下spring特定的注解集合,你可以在單元和內建測試中協同testcontext架構使用它們。請參考相應的java幫助文檔作進一步了解,包括預設的屬性,屬性别名等等。、

@contextconfiguration定義了類級别的中繼資料來決定如何為內建測試來加載和配置應用程式上下文。具體地說,@contextconfiguration聲明了用于加載上下文的應用程式上下文資源路徑和注解類。

資源路徑通常是類路徑中的xml配置檔案或者groovy腳本;而注解類通常是使用@configuration注解的類。但是,資源路徑也可以指向檔案系統中的檔案和腳本,解決類也可能是元件類等等。

1

@contextconfiguration("/test-config.xml")

2

<b>public</b> <b>class</b> xmlapplicationcontexttests {

3

// class body...

4

}

@contextconfiguration(classes = testconfig.<b>class</b>)

<b>public</b> <b>class</b> configclassapplicationcontexttests {

作為聲明資源路徑或注解類的替代方案或補充,@contextconfiguration可以用于聲明applicationcontextinitializer類。

@contextconfiguration(initializers = customcontextintializer.<b>class</b>)

<b>public</b> <b>class</b> contextinitializertests {

@contextconfiguration偶爾也被用作聲明contextloader政策。但注意,通常你不需要顯示的配置加載器,因為預設的加載器已經支援資源路徑或者注解類以及初始化器。

@contextconfiguration(locations = "/test-context.xml", loader = customcontextloader.<b>class</b>)

<b>public</b> <b>class</b> customloaderxmlapplicationcontexttests {

《Spring 5官方文檔》11內建測試 (二)

@contextconfiguration預設對繼承父類定義的資源路徑或者配置類以及上下文初始化器提供支援。

@webappconfiguration是一個用于聲明內建測試所加載的applicationcontext須是webapplicationcontext的類級别的注解。測試類的@webappconfiguration注解隻是為了保證用于測試的webapplicationcontext會被加載,它使用”file:src/main/webapp”路徑預設值作為web應用的根路徑(即,資源基路徑)。資源基路徑用于幕後建立一個mockservletcontext作為測試的webapplicationcontext的servletcontext。

@contextconfiguration

@webappconfiguration("classpath:test-web-resources")

<b>public</b> <b>class</b> webapptests {

5

注意@webappconfiguration必須和@contextconfiguration一起使用,或者在同一個測試類,或者在測試類層次結構中。請參閱@webappconfiguration幫助文檔作進一步了解。

@contexthierarchy是一個用于為內建測試定義applicationcontext層次結構的類級别的注解。@contexthierarchy應該聲明一個或多個@contextconfiguration執行個體清單,其中每一個定義上下文層次結構的一個層次。下面的例子展示了在同一個測試類中@contexthierarchy的使用方法。但是,@contexthierarchy一樣可以用于測試類的層次結構中。

@contexthierarchy({

@contextconfiguration("/parent-config.xml"),

@contextconfiguration("/child-config.xml")

})

<b>public</b> <b>class</b> contexthierarchytests {

6

7

@webappconfiguration

@contextconfiguration(classes = appconfig.<b>class</b>),

@contextconfiguration(classes = webconfig.<b>class</b>)

<b>public</b> <b>class</b> webintegrationtests {

8

@activeprofiles是一個用于當內建測試加載applicationcontext的時候聲明哪一個bean definition profiles被激活的類級别的注解。

@activeprofiles("dev")

<b>public</b> <b>class</b> developertests {

@activeprofiles({"dev", "integration"})

<b>public</b> <b>class</b> developerintegrationtests {

《Spring 5官方文檔》11內建測試 (二)

@testpropertysource是一個用于為內建測試加載applicationcontext時配置屬性檔案的位置和增加到environment中的propertysources集中的内聯屬性的類級别的注解。

測試屬性源比那些從系統環境或者java系統屬性以及通過@propertysource或者程式設計方式聲明方式增加的屬性源具有更高的優先級。而且,内聯屬性比從資源路徑加載的屬性具有更高的優先級。

下面的例子展示了如何從類路徑中聲明屬性檔案。

@testpropertysource("/test.properties")

<b>public</b> <b>class</b> myintegrationtests {

下面的例子展示了如何聲明内聯屬性。

@testpropertysource(properties = { “timezone = gmt”, “port: 4242″ })

public class myintegrationtests {

// class body…

@dirtiescontext指明測試執行期間該spring應用程式上下文已經被弄髒(也就是說通過某種方式被更改或者破壞——比如,更改單例bean的狀态)。當應用程式上下文被标為”髒”,它将從測試架構緩存中被移除并關閉。是以,spring容器将為随後需要同樣配置中繼資料的測試而被重建。

@dirtiescontext可以在同一個類或者類層次結構中的類級别和方法級别中使用。在這個場景下,應用程式上下文将在任意此注解的方法之前或之後以及目前測試類之前或之後被标為“髒”,這取決于配置的methodmode和classmode。

下面的例子解釋了在多種配置場景下什麼時候上下文會被标為“髒”。

當在一個類中聲明并将類模式設為before_class,則在目前測試類之前。

@dirtiescontext(classmode = before_class)

<b>public</b> <b>class</b> freshcontexttests {

// some tests that require a new spring container

當在一個類中聲明并将類模式設為after_class(也就是,預設的類模式),則在目前測試類之後。

@dirtiescontext

<b>public</b> <b>class</b> contextdirtyingtests {

// some tests that result in the spring container being dirtied

當在一個類中聲明并将類模式設為before_each_test_method,則在目前測試類的每個方法之前。

@dirtiescontext(classmode = before_each_test_method)

當在一個類中聲明并将類模式設為after_each_test_method,則在目前測試類的每個方法之後。

@dirtiescontext(classmode = after_each_test_method)

當在一個方法中聲明并将方法模式設為before_method,則在目前方法之前。

@dirtiescontext(methodmode = before_method)

@test

<b>public</b> <b>void</b> testprocesswhichrequiresfreshappctx() {

// some logic that requires a new spring container

當在一個方法中聲明并将方法模式設為after_method(也就是說,預設的方法模式),則在目前方法之後。

<b>public</b> <b>void</b> testprocesswhichdirtiesappctx() {

// some logic that results in the spring container being dirtied

如果@dirtiescontext被用于上下文被配置為通過@contexthierarchy定義的上下文層次中的一部分的測試中,則hierarchymode标志可用于控制如何聲明上下文緩存。預設将使用一個窮舉算法用于清除包括不僅目前層次而且與目前測試擁有共同祖先的其它上下文層次的緩存。所有在擁有共同祖先上下文的子層次的應用程式上下文都會從上下文中被移除并關閉。如果窮舉算法對于特定的使用場景顯得有點威力過猛,那麼你可以指定一個更簡單的目前層算法來代替,如下所。

<b>public</b> <b>class</b> basetests {

09

<b>public</b> <b>class</b> extendedtests <b>extends</b> basetests {

10

11

12

@dirtiescontext(hierarchymode = current_level)

13

<b>public</b> <b>void</b> test() {

14

// some logic that results in the child context being dirtied

15

16

參閱dirtiescontext.hierarchymode幫助文檔以獲得窮舉和目前層算法更詳細的了解。

@testexecutionlisteners定義了一個類級别的中繼資料,用于配置需要用testcontextmanager進行注冊的testexecutionlistener實作。通常,@testexecutionlisteners與@contextconfiguration一起使用。

@testexecutionlisteners({customtestexecutionlistener.<b>class</b>, anothertestexecutionlistener.<b>class</b>})

<b>public</b> <b>class</b> customtestexecutionlistenertests {

@testexecutionlisteners預設支援繼承監聽器。參閱幫助文檔獲得示例和更詳細的了解。

@commit指定事務性的測試方法在測試方法執行完成後對事務進行送出。@commit可以用作@rollback(false)的直接替代,以更好的傳達代碼的意圖。和@rollback一樣,@commit可以在類層次或者方法層級聲明。

@commit

<b>public</b> <b>void</b> testprocesswithoutrollback() {

// ...

@rollback指明當測試方法執行完畢的時候是否對事務性方法中的事務進行復原。如果為true,則進行復原;否則,則送出(請參加@commit)。在spring testcontext架構中,內建測試預設的rollback語義為true,即使你不顯示的指定它。

當被聲明為方法級别的注解,則@rollback為特定的方法指定復原語義,并覆寫類級别的@rollback和@commit語義。

@rollback(false)

public void testprocesswithoutrollback() {

// …

@beforetransaction指明通過spring的@transactional注解配置為需要在事務中執行的測試方法在事務開始之前先執行注解的void方法。從spring架構4.3版本起,@beforetransaction方法不再需要為public并可能被聲明為基于java8的接口的預設方法。

@beforetransaction

void beforetransaction() {

// logic to be executed before a transaction is started

@aftertransaction指明通過spring的@transactional注解配置為需要在事務中執行的測試方法在事務結束之後執行注解的void方法。從spring架構4.3版本起,@aftertransaction方法不再需要為public并可能被聲明為基于java8的接口的預設方法。

@aftertransaction

void aftertransaction() {

// logic to be executed after a transaction has ended

@sql用于注解測試類或者測試方法,以讓在內建測試過程中配置的sql腳本能夠在給定的的資料庫中得到執行。

@sql({"/test-schema.sql", "/test-user-data.sql"})

<b>public</b> <b>void</b> usertest {

// execute code that relies on the test schema and test data

@sqlconfig定義了用于決定如何解析和執行通過@sql注解配置的sql腳本。

@sql(

scripts = "/test-user-data.sql",

config = @sqlconfig(commentprefix = "`", separator = "@@")

)

// execute code that relies on the test data

@sqlgroup是一個用于聚合幾個@sql注解的容器注解。@sqlgroup可以直接使用,通過聲明幾個嵌套的@sql注解,也可以與java8的可重複注解支援協同使用,即簡單地在同一個類或方法上聲明幾個@sql注解,隐式地産生這個容器注解。

@sqlgroup({

@sql(scripts = "/test-schema.sql", config = @sqlconfig(commentprefix = "`")),

@sql("/test-user-data.sql")

)}

// execute code that uses the test schema and test data

<code>8</code>

<code>}</code>