2008-09-23 37 views
71

Tôi hiện đang tìm cách tạo thử nghiệm tự động cho dịch vụ web dựa trên dịch vụ web dựa trên dịch vụ web API JAX-RS (Java API cho RESTful Web Services).Đơn vị thử nghiệm Dịch vụ Web JAX-RS?

Tôi về cơ bản cần một cách để gửi một số đầu vào nhất định và xác minh rằng tôi nhận được phản hồi mong đợi. Tôi muốn làm điều này thông qua JUnit, nhưng tôi không chắc làm thế nào mà có thể đạt được.

Bạn sử dụng phương pháp nào để kiểm tra dịch vụ web của mình?

Cập nhật: Như entzik đã chỉ ra, việc tách dịch vụ web khỏi logic nghiệp vụ cho phép tôi kiểm tra đơn vị logic nghiệp vụ. Tuy nhiên, tôi cũng muốn kiểm tra mã trạng thái HTTP chính xác, v.v.

+5

Câu hỏi - tuy nhiên tôi muốn nói rằng nếu bạn đang thử nghiệm qua HTTP sau đó nó đập vào mắt tôi rằng đây là thử nghiệm hội nhập. –

+0

Tom. Bạn hoàn toàn đúng. Chúng ta nên tiêm một giả lập HTTP giả/container nhẹ cho việc này. Trong supertest node.js thế giới làm cho điều này. Bạn có thể mô phỏng express.js. –

Trả lời

35

Jersey đi kèm với API RESTful client tuyệt vời giúp việc viết đơn vị kiểm tra trở nên thật dễ dàng. Xem các bài kiểm tra đơn vị trong các ví dụ đi kèm với Jersey. Chúng tôi sử dụng phương pháp này để kiểm tra hỗ trợ REST theo số Apache Camel, nếu bạn quan tâm đến số test cases are here

+6

lại: bây giờ liên kết xấu Bạn có thể tìm thấy các ví dụ được đề cập trong áo/mẫu hiển thị các bài kiểm tra đơn vị, về cơ bản bằng cách sử dụng người tiêu dùng áo để tiêu thụ tài nguyên web. http://download.java.net/maven/2/com/sun/jersey/samples/bookstore/1.1.5-ea-SNAPSHOT – rogerdpack

+3

liên kết xấu một lần nữa - hãy nhớ cập nhật? –

+2

Dự án này nằm trên GitHub, tìm các bài kiểm tra trong thư mục src/test: https://github.com/jersey/jersey/tree/master/examples/bookstore-webapp – Venkat

5

Bạn có thể đã viết một số mã java thực hiện logic nghiệp vụ của mình và sau đó bạn đã tạo điểm kết thúc dịch vụ web cho nó.

Điều quan trọng cần làm là kiểm tra độc lập logic kinh doanh của bạn. Vì nó là mã java thuần túy, bạn có thể làm điều đó với các kiểm tra JUnit thông thường.

Bây giờ, vì phần dịch vụ web chỉ là điểm kết thúc, điều bạn muốn đảm bảo là hệ thống ống nước được tạo (sơ đồ, v.v.) được đồng bộ hóa với mã java của bạn. bạn có thể làm điều đó bằng cách viết các bài kiểm tra JUnit gọi trình khách java dịch vụ web được tạo ra. Điều này sẽ cho bạn biết khi bạn thay đổi chữ ký java của mình mà không cần cập nhật công cụ dịch vụ web.

Nếu hệ thống đường ống dịch vụ web của bạn được tạo tự động bởi hệ thống xây dựng của bạn ở mọi công trình, thì có thể không cần thiết để kiểm tra điểm cuối (giả sử tất cả đều được tạo đúng cách). Phụ thuộc vào mức độ hoang tưởng của bạn.

+1

Bạn hoàn toàn đúng, mặc dù tôi cũng cần kiểm tra các phản hồi HTTP thực tế được trả về, đặc biệt là các mã trạng thái HTTP. – Einar

3

Tôi sử dụng số HTTPClient (http://hc.apache.org/) của Apache để gọi Dịch vụ an toàn. Thư viện HTTP Client cho phép bạn dễ dàng thực hiện nhận, đăng hoặc bất kỳ thao tác nào khác mà bạn cần. Nếu dịch vụ của bạn sử dụng JAXB cho xml binding, bạn có thể tạo JAXBContext để tuần tự hóa và deserialize các đầu vào và đầu ra từ yêu cầu HTTP.

6

Mặc dù quá muộn từ ngày đăng câu hỏi, điều này có thể hữu ích cho những người khác có câu hỏi tương tự. Jersey đi kèm với khung kiểm tra được gọi là Jersey Test Framework cho phép bạn kiểm tra Dịch vụ web RESTful của mình, bao gồm cả mã trạng thái phản hồi. Bạn có thể sử dụng nó để chạy thử nghiệm của mình trên các vùng chứa có trọng lượng nhẹ như Grizzly, HTTPServer và/hoặc EmbeddedGlassFish. Ngoài ra, khung công tác có thể được sử dụng để chạy thử nghiệm của bạn trên một vùng chứa web thông thường như GlassFish hoặc Tomcat.

+0

Bạn có một ví dụ hay về cách xử lý các trình xử lý cuộc gọi? JerseyHttpCall -> MyResource -> CallHandler.getSomething() Làm thế nào chúng ta có thể giả lập CallHandler ở đây? –

2

Một điều quan trọng cần làm là để kiểm tra một cách độc lập logic kinh doanh của bạn

Tôi chắc chắn sẽ không cho rằng người viết mã JAX-RS và đang tìm cách để kiểm tra đơn vị sự giao diện là bằng cách nào đó, đối với một số lý do kỳ lạ, không thể giải thích, không biết gì về khái niệm rằng họ có thể kiểm tra đơn vị các phần khác của chương trình, bao gồm các lớp logic kinh doanh. Nó hầu như không hữu ích để tuyên bố rõ ràng và điểm liên tục được thực hiện rằng các phản ứng cần phải được kiểm tra, quá.

Cả Jersey và RESTEasy đều có ứng dụng khách và trong trường hợp RESTEasy, bạn có thể sử dụng cùng một báo cáo (thậm chí là yếu tố ngoài giao diện chú thích và sử dụng phía máy khách và máy chủ).

REST không phải những gì dịch vụ này có thể làm cho bạn; REST những gì bạn có thể làm cho dịch vụ này.

+0

Mọi người có thể muốn kiểm tra một số mối quan tâm cắt ngang. Ví dụ: xác nhận hợp lệ, xác thực, tiêu đề HTTP mong muốn vv Vì vậy, mọi người có thể thích kiểm tra mã JAX-RS của họ. –

+0

Trong ứng dụng của tôi, tôi sử dụng ModelMapper để "ánh xạ" từ các lớp "DTO" đến các lớp "đối tượng nghiệp vụ", được hiểu bởi các lớp "dịch vụ" cơ bản. Đây là một ví dụ về cái gì đó sẽ là tốt để kiểm tra độc lập. – jkerak

22

Bạn có thể thử REST Assured làm cho nó rất đơn giản để kiểm tra dịch vụ REST và xác thực phản hồi trong Java (sử dụng JUnit hoặc TestNG).

+1

Tôi đã bỏ phiếu cho bài đăng của bạn khiến thư viện trông đẹp, nhưng họ chắc chắn sử dụng nhiều lọ phụ thuộc ... –

10

Như James đã nói; Đã tích hợp sẵn test framework cho Jersey. Ví dụ thế giới xin chào đơn giản có thể giống như sau:

pom.xml để tích hợp maven. Khi bạn chạy mvn test. Khung bắt đầu một container grizzly. Bạn có thể sử dụng cầu cảng hoặc tomcat thông qua thay đổi phụ thuộc.

... 
<dependencies> 
    <dependency> 
    <groupId>org.glassfish.jersey.containers</groupId> 
    <artifactId>jersey-container-servlet</artifactId> 
    <version>2.16</version> 
    </dependency> 

    <dependency> 
    <groupId>org.glassfish.jersey.test-framework</groupId> 
    <artifactId>jersey-test-framework-core</artifactId> 
    <version>2.16</version> 
    <scope>test</scope> 
    </dependency> 

    <dependency> 
    <groupId>org.glassfish.jersey.test-framework.providers</groupId> 
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId> 
    <version>2.16</version> 
    <scope>test</scope> 
    </dependency> 
</dependencies> 
... 

ExampleApp.java

import javax.ws.rs.ApplicationPath; 
import javax.ws.rs.core.Application; 

@ApplicationPath("/") 
public class ExampleApp extends Application { 

} 

HelloWorld.java

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 

@Path("/") 
public final class HelloWorld { 

    @GET 
    @Path("/hello") 
    @Produces(MediaType.TEXT_PLAIN) 
    public String sayHelloWorld() { 

     return "Hello World!"; 
    } 
} 

HelloWorldTest.java

import org.glassfish.jersey.server.ResourceConfig; 
import org.glassfish.jersey.test.JerseyTest; 
import org.junit.Test; 
import javax.ws.rs.core.Application; 
import static org.junit.Assert.assertEquals; 

public class HelloWorldTest extends JerseyTest { 

    @Test 
    public void testSayHello() { 

     final String hello = target("hello").request().get(String.class); 

     assertEquals("Hello World!", hello); 
    } 

    @Override 
    protected Application configure() { 

     return new ResourceConfig(HelloWorld.class); 
    } 
} 

Bạn có thể kiểm tra this ứng dụng mẫu.

3

Hãy xem Alchemy rest client generator. Điều này có thể tạo ra một triển khai thực hiện proxy cho lớp webservice JAX-RS của bạn bằng cách sử dụng ứng dụng khách phía sau khung cảnh. Hiệu quả, bạn sẽ gọi cho bạn các phương thức webservice như các phương thức java đơn giản từ các bài kiểm tra đơn vị của bạn. Xử lý xác thực http.

Không có sự tạo mã liên quan nếu bạn chỉ cần chạy thử nghiệm để thuận tiện.

Tuyên bố từ chối trách nhiệm: Tôi là tác giả của thư viện này.

1

Vì tôi hiểu mục đích chính của việc xác thực vấn đề này là tách lớp JAX RS khỏi doanh nghiệp. Và đơn vị kiểm tra chỉ là người đầu tiên. Hai vấn đề cơ bản ở đây chúng ta phải giải quyết:

  1. Chạy thử nghiệm một số máy chủ web/ứng dụng, đặt các thành phần JAX RS trong nó. Và chỉ có họ.
  2. Dịch vụ kinh doanh giả trong các thành phần JAX RS /lớp REST.

Giải pháp đầu tiên được giải quyết bằng Arquillian. Phần thứ hai được mô tả hoàn hảo trong arquillican and mock

Dưới đây là ví dụ về mã, nó có thể khác nếu bạn sử dụng một máy chủ ứng dụng khác, nhưng tôi hy vọng bạn sẽ có được ý tưởng và lợi thế cơ bản.

import javax.inject.Inject; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 

import com.brandmaker.skinning.service.SomeBean; 

/** 
* Created by alexandr on 31.07.15. 
*/ 
@Path("/entities") 
public class RestBean 
{ 
    @Inject 
    SomeBean bean; 

    @GET 
    public String getEntiry() 
    { 
     return bean.methodToBeMoked(); 
    } 
} 

import java.util.Set; 

import javax.ws.rs.ApplicationPath; 
import javax.ws.rs.core.Application; 

import com.google.common.collect.Sets; 

/** 
*/ 
@ApplicationPath("res") 
public class JAXRSConfiguration extends Application 
{ 
    @Override 
    public Set<Class<?>> getClasses() 
    { 
     return Sets.newHashSet(RestBean.class); 
    } 
} 


public class SomeBean 
{ 
    public String methodToBeMoked() 
    { 
     return "Original"; 
    } 
} 

import javax.enterprise.inject.Specializes; 

import com.brandmaker.skinning.service.SomeBean; 

/** 
*/ 
@Specializes 
public class SomeBeanMock extends SomeBean 
{ 
    @Override 
    public String methodToBeMoked() 
    { 
     return "Mocked"; 
    } 
} 

@RunWith(Arquillian.class) 
public class RestBeanTest 
{ 
    @Deployment 
    public static WebArchive createDeployment() { 
     WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war") 
       .addClasses(JAXRSConfiguration.class, RestBean.class, SomeBean.class, SomeBeanMock.class) 
       .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); 
     System.out.println(war.toString(true)); 
     return war; 
    } 

    @Test 
    public void should_create_greeting() { 
     Client client = ClientBuilder.newClient(); 
     WebTarget target = client.target("http://127.0.0.1:8181/test/res/entities"); 
     //Building the request i.e a GET request to the RESTful Webservice defined 
     //by the URI in the WebTarget instance. 
     Invocation invocation = target.request().buildGet(); 
     //Invoking the request to the RESTful API and capturing the Response. 
     Response response = invocation.invoke(); 
     //As we know that this RESTful Webserivce returns the XML data which can be unmarshalled 
     //into the instance of Books by using JAXB. 
     Assert.assertEquals("Mocked", response.readEntity(String.class)); 
    } 
} 

Một vài ghi chú: Cấu hình RS

  1. JAX mà không web.xml được sử dụng ở đây.
  2. Ứng dụng khách JAX RS được sử dụng tại đây (không có RESTEasy/Jersey, chúng lộ API thuận tiện hơn)
  3. Khi bắt đầu thử nghiệm, vận động viên Arquillian bắt đầu hoạt động. Here bạn có thể tìm cách cấu hình các kiểm tra cho Arquillian bằng máy chủ ứng dụng cần thiết.
  4. Tùy thuộc vào máy chủ ứng dụng đã chọn, một url trong bài kiểm tra sẽ khác một chút. Một cổng khác có thể được sử dụng. 8181 là được Glassfish sử dụng Nhúng trong ví dụ của tôi.

Hy vọng, nó sẽ hữu ích.

+0

là loại điều này được hỗ trợ bởi khung kiểm thử được xây dựng trong bộ đệm? Tôi chỉ do dự để thêm "một khuôn khổ khác" và tất cả các lọ của nó vào dự án của tôi nếu tôi đã có một cái gì đó có sẵn với Jersey. – jkerak

2

Giữ đơn giản. Hãy xem https://github.com/valid4j/http-matchers có thể được nhập từ Maven Central.

<dependency> 
     <groupId>org.valid4j</groupId> 
     <artifactId>http-matchers</artifactId> 
     <version>1.0</version> 
    </dependency> 

Cách sử dụng Ví dụ:

// Statically import the library entry point: 
import static org.valid4j.matchers.http.HttpResponseMatchers.*; 

// Invoke your web service using plain JAX-RS. E.g: 
Client client = ClientBuilder.newClient(); 
Response response = client.target("http://example.org/hello").request("text/plain").get(); 

// Verify the response 
assertThat(response, hasStatus(Status.OK)); 
assertThat(response, hasHeader("Content-Encoding", equalTo("gzip"))); 
assertThat(response, hasEntity(equalTo("content"))); 
// etc... 
Các vấn đề liên quan