日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JUnit规则

發(fā)布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JUnit规则 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

第一次偶然發(fā)現(xiàn)JUnit @Rule批注時,我對此概念有些惱火。 在測試用例中擁有一個公共領(lǐng)域似乎有些奇怪,因此我不愿意定期使用它。 但是一段時間后,我習(xí)慣了這一點,事實證明,規(guī)則可以通過多種方式簡化編寫測試的過程。 這篇文章簡要介紹了該概念,并簡要列舉了一些規(guī)則的優(yōu)點。

什么是JUnit規(guī)則?

讓我們從一個現(xiàn)成的JUnit規(guī)則開始。 TemporaryFolder是一個測試幫助程序,可用于為臨時內(nèi)容1創(chuàng)建位于文件系統(tǒng)目錄下的文件和文件夾。 TemporaryFolder的有趣之處在于,它保證在測試方法完成時刪除其文件和文件夾2 。 為了按預(yù)期方式工作,必須將臨時文件夾實例分配給@Rule注釋字段,該字段必須是公共的(不是靜態(tài)的),并且是TestRule的子類型:

public class MyTest {@Rulepublic TemporaryFolder temporaryFolder = new TemporaryFolder();@Testpublic void testRun() throws IOException {assertTrue( temporaryFolder.newFolder().exists() );} }


它是如何工作的?

規(guī)則提供了一種攔截測試方法調(diào)用的可能性,就像AOP框架一樣。 與AspectJ中的周圍建議相比,您可以在實際測試執(zhí)行之前和/或之后做一些有用的事情3 。 盡管這聽起來很復(fù)雜,但是卻很容易實現(xiàn)。

規(guī)則定義的API部分必須實現(xiàn)TestRule。 此接口稱為apply的唯一方法返回Statement 。 Statement s表示(簡單地說)在JUnit運行時中的測試,而Statement#evaluate()執(zhí)行它們。 現(xiàn)在,基本思想是提供Statement包裝擴展,該包裝可以通過覆蓋Statement#evaluate()來進行實際貢獻:

public class MyRule implements TestRule {@Overridepublic Statement apply( Statement base, Description description ) {return new MyStatement( base );} }public class MyStatement extends Statement {private final Statement base;public MyStatement( Statement base ) {this.base = base;}@Overridepublic void evaluate() throws Throwable {System.out.println( 'before' );try {base.evaluate();} finally {System.out.println( 'after' );}} }

MyStatement作為包裝器實現(xiàn),在MyRule#apply(Statement,Destination)使用該包裝器包裝作為參數(shù)給出的原始語句。 很容易看出,包裝程序覆蓋了Statement#evaluate()在實際測試4之前和之后做一些事情。

下一個代碼片段顯示如何與上面的TemporaryFolder完全一樣地使用MyRule :

public class MyTest {@Rulepublic MyRule myRule = new MyRule();@Testpublic void testRun() {System.out.println( 'during' );} }

啟動測試用例將導(dǎo)致以下控制臺輸出,這證明我們的示例規(guī)則可以按預(yù)期工作。 測試執(zhí)行被我們的規(guī)則攔截和修改,以在測試的“期間”前后打印“之前”和“之后”:

before during after

現(xiàn)在已經(jīng)了解了基礎(chǔ)知識,下面讓我們看一下您可以使用規(guī)則執(zhí)行的更有用的事情。

測試治具

從相應(yīng)的維基百科部分引用的“測試裝置”是運行測試并期望獲得特定結(jié)果所必須具備的所有條件。 通常,通過處理單元測試框架的setUp()和tearDown()事件來創(chuàng)建固定裝置。

使用JUnit,這通常看起來像這樣:

public class MyTest {private MyFixture myFixture;@Testpublic void testRun1() {myFixture.configure1();// do some testing here}@Testpublic void testRun2() {myFixture.configure2();// do some testing here}@Beforepublic void setUp() {myFixture = new MyFixture();}@Afterpublic void tearDown() {myFixture.dispose();} }

考慮您在許多測試中以上面顯示的方式使用特定的夾具。 在那種情況下,最好擺脫setUp()和tearDown()方法。 鑒于以上各節(jié),我們現(xiàn)在知道可以通過更改MyFixture來實現(xiàn)TestRule來完成。 適當(dāng)?shù)腟tatement實現(xiàn)必須確保它調(diào)用MyFixture#dispose()并且看起來可能像這樣:

public class MyFixtureStatement extends Statement {private final Statement base;private final MyFixture fixture;public MyFixtureStatement( Statement base, MyFixture fixture ) {this.base = base;this.fixture = fixture;}@Overridepublic void evaluate() throws Throwable {try {base.evaluate();} finally {fixture.dispose();}} }

有了這個,上面的測試可以重寫為:

public class MyTest {@Rulepublic MyFixture myFixture = new MyFixture();@Testpublic void testRun1() {myFixture.configure1();// do some testing here}@Testpublic void testRun2() {myFixture.configure2();// do some testing here} }

在很多情況下,我開始欣賞使用規(guī)則編寫測試的更為緊湊的形式,但是可以肯定的是,這也是一個品味問題以及您認為更適合閱讀的內(nèi)容5

帶有方法注釋的夾具配置

到目前為止,我已默默地忽略了TestRule#apply(Statement,Description)的Description參數(shù)。 通常, Description描述了將要運行或已經(jīng)運行的測試。 但它也允許訪問有關(guān)底層java方法的一些反射信息。 除其他外,有可能讀取這種方法附帶的注釋。 這使我們能夠?qū)⒁?guī)則與方法注釋結(jié)合起來,以方便配置TestRule 。

考慮以下注釋類型:

@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Configuration {String value(); }

與MyFixture#apply(Statement,Destination)中的以下代碼段結(jié)合使用,該代碼讀取注釋為特定測試方法的配置值…

Configuration annotation= description.getAnnotation( Configuration.class ); String value = annotation.value(); // do something useful with value

…上面演示MyFixture規(guī)則用法的MyFixture可以重寫為:

public class MyTest {@Rulepublic MyFixture myFixture = new MyFixture();@Test@Configuration( value = 'configuration1' )public void testRun1() {// do some testing here}@Test@Configuration( value = 'configuration2' )public void testRun2() {// do some testing here} }

當(dāng)然,由于注釋僅允許Enum , Class es或String文字作為參數(shù),因此后一種方法存在局限性。 但是在某些用例中,這已經(jīng)足夠了。 restfuse庫提供了一個很好的示例,該示例將規(guī)則與方法注釋結(jié)合使用。 如果您對現(xiàn)實世界的示例感興趣,則應(yīng)查看Destination規(guī)則6的庫實現(xiàn)。

最后,剩下的唯一要說的是,我很想聽聽您關(guān)于可以用來簡化日常測試工作的JUnit規(guī)則的其他有用示例的信息:

  • 通常由System.getProperty( 'java.io.tmpdir' );返回的目錄System.getProperty( 'java.io.tmpdir' ); ?
  • 在查看TemporaryFolder的實現(xiàn)時,我必須注意,它不會檢查文件刪除是否成功。 這可能是打開的文件句柄的情況下,一個薄弱點?
  • 值得的是,您甚至可以用其他方法代替完整的測試方法?
  • 包裝語句的委托放入try...finally塊中,以確保執(zhí)行測試后的功能,即使測試失敗。 在這種情況下,一個AssertionError會被拋出,并且不是在finally塊語句都將跳過?
  • 你可能注意到TemporaryFolder之初例子也不外乎夾具的使用情況?
  • 請注意,restfuse的Destination類實現(xiàn)了MethodRule而不是TestRule 。 這篇文章基于最新的JUnit版本,其中MethodRule被標(biāo)記為@Deprecated 。 TestRule代替MethodRule 。 但是,鑒于此職位的知識,仍然應(yīng)該很容易理解實現(xiàn)?

  • 參考:來自JCG合作伙伴 Frank Appel的JUnit規(guī)則 ,位于Code Affine博客上。

    翻譯自: https://www.javacodegeeks.com/2012/11/junit-rules.html

    總結(jié)

    以上是生活随笔為你收集整理的JUnit规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。