Java RESTful API集成測試

這篇文章將重點介紹為RESTful API(帶有JSON有效負載)編寫Java集成測試的基本原理和機制。

目的是對技術進行介紹,并為基本正確性編寫一些測試。 這些示例將使用最新版本的GitHub REST API。

對于內部應用程序,這種測試通常將在持續集成過程中作為后期步驟運行,并在已部署REST API后使用它。

在測試REST資源時,通常應承擔一些正交的職責,測試應重點關注:

  • HTTP 響應代碼
  • 響應中的其他HTTP 標頭
  • 有效負載 (JSON,XML)

每個測試應僅關注單個職責并包括單個聲明。 專注于清晰的分離總是有好處的,但是當進行這種黑盒測試時,它就顯得尤為重要,因為通常的趨勢是在一開始就編寫復雜的測試方案。

集成測試的另一個重要方面是遵守單一抽象原理–測試中的邏輯應以較高的層次編寫。 諸如創建請求,將HTTP請求發送到服務器,處理IO等之類的細節不應內聯而是通過實用程序方法來完成。

測試HTTP響應代碼

@Test
public void givenUserDoesNotExists_whenUserInfoIsRetrieved_then404IsReceived()throws ClientProtocolException, IOException{// GivenString name = randomAlphabetic( 8 );HttpUriRequest request = new HttpGet( "https://api.github.com/users/" + name );// WhenHttpResponse httpResponse = httpClient.execute( request );// ThenRestAssert.assertResponseCodeIs( httpResponse, 404 );
}

這是一個相當簡單的測試,它驗證基本的快樂路徑在起作用,而不會增加測試套件的復雜性。 如果由于某種原因它失敗了,那么在此URL修復之前,無需檢查該URL的任何其他測試。 由于驗證響應代碼是集成測試套件中最常見的斷言之一,因此將使用自定義斷言 。

public static void assertResponseCodeIs( final HttpResponse response, final int expectedCode ){final int statusCode = httpResponse.getStatusLine().getStatusCode();assertEquals( expectedCode, statusCode );
}

測試HTTP響應的其他標頭

@Test
public void givenRequestWithNoAcceptHeader_whenRequestIsExecuted_thenDefaultResponseContentTypeIsJson()throws ClientProtocolException, IOException{// GivenString jsonMimeType = "application/json";HttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );// WhenHttpResponse response = this.httpClient.execute( request );// ThenString mimeType = EntityUtils.getContentMimeType( response.getEntity() );assertEquals( jsonMimeType, mimeType );
}

這樣可以確保在請求用戶詳細信息時的響應實際上是JSON。 被測試功能有一個邏輯上的進展-首先是響應代碼,以確保請求正常,然后是請求的mime類型,然后才是對實際JSON是否正確的驗證。

測試HTTP響應的JSON有效負載

@Test
public void givenUserExists_whenUserInformationIsRetrieved_thenRetrievedResourceIsCorrect()throws ClientProtocolException, IOException{// GivenHttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );// WhenHttpResponse response = new DefaultHttpClient().execute( request );// ThenGitHubUser resource =RetrieveUtil.retrieveResourceFromResponse( response, GitHubUser.class );assertThat( "eugenp", Matchers.is( resource.getLogin() ) );
}

在這種情況下,我知道GitHub資源的默認表示形式是JSON,但通常應將響應的Content-Type標頭與請求的Accept標頭一起進行測試-客戶端通過Accept請求特定的表示類型,服務器應該兌現。

測試工具

以下是使測試保持較高抽象水平的實用程序:

–使用JSON有效負載(或直接使用POJO)裝飾HTTP請求:

public static < T >HttpEntityEnclosingRequest decorateRequestWithResource( final HttpEntityEnclosingRequest request, final T resource )throws IOException{Preconditions.checkNotNull( request );Preconditions.checkNotNull( resource );final String resourceAsJson = JsonUtil.convertResourceToJson( resource );return JsonUtil.decorateRequestWithJson( request, resourceAsJson );
}public static HttpEntityEnclosingRequest decorateRequestWithJson( final HttpEntityEnclosingRequest request, final String json )throws UnsupportedEncodingException{Preconditions.checkNotNull( request );Preconditions.checkNotNull( json );request.setHeader( HttpConstants.CONTENT_TYPE_HEADER, "application/json" );request.setEntity( new StringEntity( json ) );return request;
}

–從HTTP響應中檢索JSON有效負載(或直接獲取POJO):

public static String retrieveJsonFromResponse( final HttpResponse response )throws IOException{Preconditions.checkNotNull( response );return IOUtils.toString( response.getEntity().getContent() );
}public static < T >T retrieveResourceFromResponse( final HttpResponse response, final Class< T > clazz ) throws IOException{Preconditions.checkNotNull( response );Preconditions.checkNotNull( clazz );final String jsonFromResponse = retrieveJsonFromResponse( response );return ConvertUtil.convertJsonToResource( jsonFromResponse, clazz );
}

–從Java對象(PO??JO)到JSON的轉換實用程序:

public static < T >String convertResourceToJson( final T resource )throws IOException{Preconditions.checkNotNull( resource );return new ObjectMapper().writeValueAsString( resource );
}public static < T >T convertJsonToResource( final String json, final Class< T > clazzOfResource ) throws IOException{Preconditions.checkNotNull( json );Preconditions.checkNotNull( clazzOfResource );return new ObjectMapper().readValue( json, clazzOfResource );
}

依存關系

這些實用程序和測試利用了以下庫,所有這些庫都可以在Maven Central中使用:

  • Apache HttpCore和HttpClient
  • Apache Commons IO
  • Apache Commons Lang
  • 杰克遜
  • 番石榴
  • Hamcrest

結論

這只是完整的集成測試套件應有的一部分。 這些測試著重于確保REST API的基本正確性,而不涉及更復雜的場景,API的可發現性,對同一資源或其他更高級區域使用不同表示形式的情況。 我將在進一步的文章中討論這些問題,同時在github上檢出整個項目 。

參考:我們的JCG合作伙伴 Eugen Paraschiv在baeldung博客上 介紹了RESTful API的Java集成測試 。

相關文章 :
  • Tomcat 7上具有RESTeasy JAX-RS的RESTful Web服務-Eclipse和Maven項目
  • Spring3 RESTful Web服務
  • Spring 3使用JUnit 4進行測試– ContextConfiguration和AbstractTransactionalJUnit4SpringContextTests
  • 單元和集成測試的代碼覆蓋率
  • jqGrid,REST,AJAX和Spring MVC集成
  • JUnit 4.9(測試版3)中的規則
  • Java教程和Android教程列表

翻譯自: https://www.javacodegeeks.com/2011/10/java-restful-api-integration-testing.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374208.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374208.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374208.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java警惕自增的陷阱

public class proposal{public static void main(String[] args) {int count0;for(int i0;i<10;i){countcount;}System.out.println(count);}}結果輸出&#xff1a;0/*步驟一&#xff1a;JMV吧count值&#xff08;其值是0&#xff09;拷貝到臨時變量區&#xff1b;步驟二:co…

[LindCode] Binary Tree Postorder Traversal

Binary Tree Postorder Traversal Given a binary tree, return the postorder traversal of its nodes values. Example Given binary tree {1,#,2,3}, 1\2/3return [3,2,1]. Challenge Can you do it without recursion? SOLUTION 1: recursion&#xff1a; 分治法解決之&am…

九齊NY8B072A單片機使用筆記(一)TIMER0定時器

先上代碼 //8bit count up , max 0xFF void Ny8b072a_Timer0_Init(void) {PCON1 C_TMR0_Dis; // Disable Timer0//1 * (255 - 5) 250usTMR0 5; // Load 0x00 to TMR0 (Initial Timer0 register)//16M 2T Div8 1usT0MD C_PS0_TMR0 | C_PS0_Div8 ; // Prescaler0 is assign…

python菜鳥教程split_Python split()方法

網頁地址解析&#xff1a; #codingutf-8 str"http://www.runoob.com/python/att-string-split.html" print("0:%s"%str.split("/")[-1]) print("1:%s"%str.split("/")[-2]) print("2:%s"%str.split("/"…

金山毒霸垃圾清理

金山毒霸-垃圾清理-單文件封裝,清潔潔癖的愛好&#xff01; 實話&#xff0c;金山的軟件確實不錯。展望金山可以在軟件行業&#xff0c;做出讓世界都使用的。為國人扛起一片天 下載地址&#xff1a; http://pan.baidu.com/s/1dFa7GdV轉載于:https://www.cnblogs.com/xiaochina/…

并發優化–減少鎖粒度

在高負載多線程應用程序中&#xff0c;性能非常重要。 開發人員必須意識到并發問題才能獲得更好的性能。 當我們需要并發時&#xff0c;我們通常擁有必須由兩個或更多線程共享的資源。 在這種情況下&#xff0c;我們有一個競爭條件 &#xff0c;其中只有一個線程&#xff08;在…

Java1.5增加了新特性:可變參數

/*Java 可變參數Java1.5增加了新特性&#xff1a;可變參數&#xff1a;適用于參數個數不確定&#xff0c;類型確定的情況&#xff0c;java把可變參數當做數組處理。注意&#xff1a;可變參數必須位于最后一項。當可變參數個數多余一個時&#xff0c;必將有一個不是最后一項&…

C語言代碼規范(十)花里胡哨代碼鑒賞

一、宏定義篇 1、作者的目的是防止GPIO口賦值超過1。但是有明顯自覺高人一等&#xff0c;瞧不起讀者的感覺。 uint8_t not_func(uint8_t sw) {return (sw?1:0); }#define LED1(sw) PA12not_func(sw)修改建議&#xff1a; #define LED1 PA12 #define LED_ON 0 #de…

python-break循環中斷

Python break語句&#xff0c;就像在C語言中&#xff0c;打破了最小封閉for或while循環。 break語句用來終止循環語句&#xff0c;即循環條件沒有False條件或者序列還沒被完全遞歸完&#xff0c;也會停止執行循環語句。 break語句用在while和for循環中。 如果您使用嵌套循環&am…

正則表達式驗證六位數以上數字,符號,字母任意兩種混合的密碼驗證策略

^(?![0-9]$)(?![a-zA-Z]$)(?!([^(0-9a-zA-Z)]|[\(\)])$)([^(0-9a-zA-Z)]|[\(\)]|[a-zA-Z]|[0-9]){6,}$這個正則如果是單獨的數字&#xff0c;字符和符號&#xff0c;是不能通過的&#xff0c;少于6位也不行&#xff0c;希望大家可以繼續驗證正確性吧轉載于:https://www.cnbl…

python post請求實例_Python使用requests發送POST請求實例代碼

本文研究的主要是Python使用requests發送POST請求的相關內容&#xff0c;具體介紹如下。 一個http請求包括三個部分&#xff0c;為別為請求行&#xff0c;請求報頭&#xff0c;消息主體&#xff0c;類似以下這樣&#xff1a; 請求行 請求報頭 消息主體 HTTP協議規定post提交的數…

Java Micro-Benchmarking:如何編寫正確的基準

幾個月前&#xff0c;我寫了一篇文章比較循環的短索引的性能 。 我問自己關于使用短褲作為循環迭代次數很少的循環的性能。 在Java語言中&#xff0c;所有對整數的操作都是int進行的。 因此&#xff0c;如果我們使用short作為循環索引&#xff0c;則在每次迭代時都將進行類型轉…

新唐M031學習筆記(一)定時器基礎計數應用

先上代碼 void Hw_Timer0_Init(void) {//20:100ms 200:10ms 2000:1ms 20000:100us 200000:10us TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 200000);/* Update prescale to set proper resolution. */TIMER_SET_PRESCALE_VALUE(TIMER0, 1); /* Enable Timer0 interrupt */TI…

java三元操作符注意

/* 三元操作符的類型務必一致 */ public class proposal_3 {public static void main(String[] args) {int i80;String sString.valueOf(i<90?90:100);String s1String.valueOf(i<90?90:100.0);if(s.equals(s1))System.out.println("s和s1相等&#xff01;"…

緩解口臭可以喝一種水

河南中醫學院第一附屬醫院耳鼻喉科主任醫師梅祥勝點評&#xff1a;通常情況下&#xff0c;口臭跟脾胃濕熱有關。中醫講&#xff1a;“胃主受納&#xff0c;脾主運化&#xff1b;胃氣主降&#xff0c;使飲食物及 其糟粕得以下行&#xff0c;脾氣主升&#xff0c;則飲食物之精華得…

asp.net+mvc+easyui+sqlite 簡單用戶系統學習之旅(二)—— easyui的簡單實用

下面開始在UserManager.Web中利用easyUI構建web。 1. 先刪除自帶的controllers、models和views&#xff08;里面的shared和web.config可以保存&#xff09;下面的文件 2. 要利用easyUI&#xff0c;首先去網上下載jquery-easyui-1.3.2.zip&#xff0c;同時下載一份EasyUI-1.3.2.…

adc如何獲取周期_LOL:千玨擁有ADC最需要的位移和無敵能力,為什么沒人用她打下路?...

— 點擊藍字 關注我們 —英雄聯盟自國服上線以來&#xff0c;已經陪伴玩家走過了9個年頭&#xff0c;目前英雄聯盟中的英雄數量已經達到了151位&#xff0c;每一位都各具特色。千玨是一位深受玩家們喜愛的英雄&#xff0c;其在官方英雄的定位中&#xff0c;屬于打野英雄&#x…

航順HK32F030MF4P6 RST作GPIO SWCLK作EXTI5 SWDIO作ADC_AIN0

老習慣&#xff0c;先上代碼 void Hw_Input_Chage_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_IOMUX, ENABLE);GPIOMUX->NRST_PIN_KEY (uint32_t)(0x00005AE1); //KEY…

centos7.2下編譯安裝git

centos最新的7.2版本&#xff0c;git居然是1.8&#xff0c;而最新的git版本是2.9 差的太多了&#xff0c;何況git2.0后有大更新。于是&#xff0c;我決定編譯安裝。中間有一點小破折&#xff0c;記錄一下&#xff0c;備忘。 1&#xff0c;下載最新的源碼&#xff0c;網址&#…

java務必讓常量的值在運行期保持不變

/* 常量就是常量&#xff0c;在編譯期就必須確定其值&#xff0c;不應該在運行期更改&#xff0c;否則程序的可讀性會非常差 */public class proposal_2 {interface Const{public static final int RAND_CONSTnew Random().nextInt();}public static void main(String[] arg…