Java RESTful API集成测试
目的是對(duì)技術(shù)進(jìn)行介紹,并為基本正確性編寫一些測(cè)試。 這些示例將使用最新版本的GitHub REST API。
對(duì)于內(nèi)部應(yīng)用程序,這種測(cè)試通常將在持續(xù)集成過(guò)程中作為后期步驟運(yùn)行,并在已部署REST API后使用它。
在測(cè)試REST資源時(shí),通常應(yīng)承擔(dān)一些正交的職責(zé),測(cè)試應(yīng)重點(diǎn)關(guān)注:
- HTTP 響應(yīng)代碼
- 響應(yīng)中的其他HTTP 標(biāo)頭
- 有效負(fù)載 (JSON,XML)
每個(gè)測(cè)試應(yīng)僅關(guān)注單個(gè)職責(zé)并包括單個(gè)聲明。 專注于清晰的分離總是有好處的,但是當(dāng)進(jìn)行這種黑盒測(cè)試時(shí),它就顯得尤為重要,因?yàn)橥ǔ5内厔?shì)是在一開始就編寫復(fù)雜的測(cè)試方案。
集成測(cè)試的另一個(gè)重要方面是遵守單一抽象原理–測(cè)試中的邏輯應(yīng)以較高的層次編寫。 諸如創(chuàng)建請(qǐng)求,將HTTP請(qǐng)求發(fā)送到服務(wù)器,處理IO等之類的細(xì)節(jié)不應(yīng)內(nèi)聯(lián)而是通過(guò)實(shí)用程序方法來(lái)完成。
測(cè)試HTTP響應(yīng)代碼
@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 ); }這是一個(gè)相當(dāng)簡(jiǎn)單的測(cè)試,它驗(yàn)證基本的快樂(lè)路徑在起作用,而不會(huì)增加測(cè)試套件的復(fù)雜性。 如果由于某種原因它失敗了,那么在此URL修復(fù)之前,無(wú)需檢查該URL的任何其他測(cè)試。 由于驗(yàn)證響應(yīng)代碼是集成測(cè)試套件中最常見的斷言之一,因此將使用自定義斷言 。
public static void assertResponseCodeIs( final HttpResponse response, final int expectedCode ){final int statusCode = httpResponse.getStatusLine().getStatusCode();assertEquals( expectedCode, statusCode ); }測(cè)試HTTP響應(yīng)的其他標(biāo)頭
@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 ); }這樣可以確保在請(qǐng)求用戶詳細(xì)信息時(shí)的響應(yīng)實(shí)際上是JSON。 被測(cè)試功能有一個(gè)邏輯上的進(jìn)展-首先是響應(yīng)代碼,以確保請(qǐng)求正常,然后是請(qǐng)求的mime類型,然后才是對(duì)實(shí)際JSON是否正確的驗(yàn)證。
測(cè)試HTTP響應(yīng)的JSON有效負(fù)載
@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資源的默認(rèn)表示形式是JSON,但通常應(yīng)將響應(yīng)的Content-Type標(biāo)頭與請(qǐng)求的Accept標(biāo)頭一起進(jìn)行測(cè)試-客戶端通過(guò)Accept請(qǐng)求特定的表示類型,服務(wù)器應(yīng)該兌現(xiàn)。
測(cè)試工具
以下是使測(cè)試保持較高抽象水平的實(shí)用程序:
–使用JSON有效負(fù)載(或直接使用POJO)裝飾HTTP請(qǐng)求:
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響應(yīng)中檢索JSON有效負(fù)載(或直接獲取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對(duì)象(PO??JO)到JSON的轉(zhuǎn)換實(shí)用程序:
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 ); }依存關(guān)系
這些實(shí)用程序和測(cè)試?yán)昧艘韵聨?kù),所有這些庫(kù)都可以在Maven Central中使用:
- Apache HttpCore和HttpClient
- Apache Commons IO
- Apache Commons Lang
- 杰克遜
- 番石榴
- Hamcrest
結(jié)論
這只是完整的集成測(cè)試套件應(yīng)有的一部分。 這些測(cè)試著重于確保REST API的基本正確性,而不涉及更復(fù)雜的場(chǎng)景,API的可發(fā)現(xiàn)性,對(duì)同一資源或其他更高級(jí)區(qū)域使用不同表示形式的情況。 我將在進(jìn)一步的文章中討論這些問(wèn)題,同時(shí)在github上檢出整個(gè)項(xiàng)目 。
參考:我們的JCG合作伙伴 Eugen Paraschiv在baeldung博客上 介紹了RESTful API的Java集成測(cè)試 。
相關(guān)文章 :- Tomcat 7上具有RESTeasy JAX-RS的RESTful Web服務(wù)-Eclipse和Maven項(xiàng)目
- Spring3 RESTful Web服務(wù)
- Spring 3使用JUnit 4進(jìn)行測(cè)試– ContextConfiguration和AbstractTransactionalJUnit4SpringContextTests
- 單元和集成測(cè)試的代碼覆蓋率
- jqGrid,REST,AJAX和Spring MVC集成
- JUnit 4.9(測(cè)試版3)中的規(guī)則
- Java教程和Android教程列表
翻譯自: https://www.javacodegeeks.com/2011/10/java-restful-api-integration-testing.html
總結(jié)
以上是生活随笔為你收集整理的Java RESTful API集成测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 有益的CountDownLatch和棘手
- 下一篇: Java Micro-Benchmark