2010-10-04 55 views
5

Hãy nói rằng tôi đang viết một ứng dụng và tôi cần để có thể làm điều gì đó như thế này:https giả yêu cầu trong java

String url = "https://someurl/"; 
GetMethod method = new GetMethod(URLEncoder.encode(url)); 
String content = method.getResponseBodyAsString(); 

Có cách nào để cung cấp một máy chủ giả mà có thể cho tôi xử lý Yêu cầu https? Những gì tôi đang tìm kiếm là một cách để viết các bài kiểm tra đơn vị, nhưng tôi cần để có thể thử phần thực sự đi ra ngoài để https://someurl vì vậy tôi có thể nhận được một phản ứng được biết đến trở lại.

+0

có thể trùng lặp của http://stackoverflow.com/q/393099/2093341 – Andrea

Trả lời

3

Bạn về cơ bản có hai lựa chọn:

1. Tóm tắt cuộc gọi đến khuôn khổ và kiểm tra điều này.

Ví dụ: tái cấu trúc mã để cho phép bạn chèn một triển khai mô hình tại một số điểm. Có rất nhiều cách để làm điều này. ví dụ. tạo một getUrlAsString() và giả lập điều đó. (cũng đề nghị ở trên). Hoặc tạo một nhà máy getter url trả về một đối tượng GetMethod. Các nhà máy sau đó có thể được chế giễu.

2. Khởi động máy chủ ứng dụng như một phần của thử nghiệm và sau đó chạy phương pháp của bạn chống lại nó. (Đây sẽ là thử nghiệm tích hợp nhiều hơn)

Điều này có thể đạt được bằng nhiều cách. Điều này có thể nằm ngoài thử nghiệm, ví dụ: plugin maven jetty. hoặc kiểm tra có thể lập trình khởi động máy chủ. xem: http://docs.codehaus.org/display/JETTY/Embedding+Jetty

Chạy qua https sẽ làm phức tạp điều này nhưng vẫn có thể có chứng chỉ tự ký. Nhưng tôi muốn tự hỏi - chính xác bạn muốn kiểm tra cái gì? Tôi nghi ngờ bạn thực sự cần phải kiểm tra chức năng https, một công nghệ đã được chứng minh của nó.

Cá nhân tôi sẽ chọn tùy chọn 1 - bạn đang cố kiểm tra chức năng của thư viện bên ngoài. Điều đó thường không cần thiết. Ngoài ra, thực hành tốt là trừu tượng hóa các phụ thuộc của bạn cho các thư viện bên ngoài.

Hy vọng điều này sẽ hữu ích.

1

Hãy xem JWebUnit http://jwebunit.sourceforge.net/

Dưới đây là một ví dụ về một bài kiểm tra ... nó thực sự khá trực quan.

public class ExampleWebTestCase extends WebTestCase { 
    public void setUp() { 
     super.setUp(); 
     setBaseUrl("http://localhost:8080/test"); 
    } 

    public void test1() { 
     beginAt("/home"); 
     clickLink("login"); 
     assertTitleEquals("Login"); 
     setTextField("username", "test"); 
     setTextField("password", "test123"); 
     submit(); 
     assertTitleEquals("Welcome, test!"); 
    } 
} 
+0

vâng, tôi quen với JWebUnit, nhưng ở đây tôi cần để có thể để chế nhạo url thực tế đang được phục vụ lên. JWebUnit hoạt động khi trang web/dịch vụ bạn đang gọi thực sự đang chạy. – dcp

1

Bạn luôn có thể khởi chạy máy chủ thttpd như một phần của thử nghiệm đơn vị để phân phối các yêu cầu cục bộ. Mặc dù, lý tưởng, bạn có một thử nghiệm tốt GetMethod, và sau đó bạn chỉ có thể thử nó, và không phải thực sự có một máy chủ từ xa xung quanh cho tất cả các bài kiểm tra của bạn.

Tài

1

Bạn có thể quấn mã mà trong một số lớp và có WebClient.getUrl() và sau đó thử (ví dụ jmock) phương pháp đó để trả hồ sơ lưu trữ - nói

expectation { 
    oneOf("https://someurl/"), will(returnValue(someHTML)); 
} 
2

Nếu bạn đang viết kiểm tra đơn vị, bạn không muốn ant bất kỳ phụ thuộc bên ngoài. từ api,

GetMethod 

kéo dài

HttpMethod 

vì vậy bạn có thể dễ dàng thử nó với thư viện mocking yêu thích của bạn. Số điện thoại

method.getResponseBodyAsString() 

gọi để trả lại bất kỳ dữ liệu nào bạn muốn.

+0

Nhưng GetMethod đang được tạo ra trong chính mã, không phải trong thử nghiệm đơn vị của tôi, vì vậy tôi không thể giả lập nó. – dcp

+0

Tôi không hiểu, bạn không kiểm soát mã bạn đang thử nghiệm? – hvgotcodes

+0

Tôi kiểm soát mã, nhưng đối tượng GetMethod đang được tạo bên trong phương thức mà tôi đang thử nghiệm, vì vậy tôi không thể truyền vào đối tượng giả. Cách thức hoạt động của mô hình là bạn thiết lập nó trước và truyền nó cho bất kỳ phương pháp nào bạn đang thử nghiệm, nhưng trong trường hợp này, đối tượng GetMethod đang được tạo bên trong phương thức, vì vậy tôi không thể truyền nó vào. không rõ ràng, xin vui lòng cho tôi biết. – dcp

1

Để những gì kéo dài khiến bạn quan tâm chế giễu này "Nhận" cuộc gọi, bởi vì nếu bạn đang tìm kiếm một vị tướng mục đích mocking khuôn khổ cho Java mà tích hợp tốt với JUnit và cho phép thiết lập kỳ vọng được tự động khẳng định khi kết hợp vào một bộ JUnit, sau đó bạn thực sự nên xem xét jMock.

Bây giờ không có mã hơn, thật khó để xác định xem đây là thực sự những gì bạn đang tìm kiếm, nhưng một (hơi vô dụng) Ví dụ, một cái gì đó tương tự như mã ví dụ bạn đã viết, sẽ đi một cái gì đó như thế này:

class GetMethodTest { 
@Rule public JUnitRuleMockery context = new JunitRuleMockery(); 

@Test 
public void testGetMethod() throws Exception { 
    // Setup mocked object with expectations 
    final GetMethod method = context.mock(GetMethod.class); 
    context.checking(new Expectations() {{ 
     oneOf (method).getResponseBodyAsString(); 
     will(returnValue("Response text goes here")); 
    }}); 

    // Now do the checking against mocked object 
    String content = method.getResponseBodyAsString(); 
} 
} 
+0

Sẽ không thực sự hoạt động trong trường hợp của tôi, hãy xem nhận xét của tôi về hvgotcodes. – dcp

+0

Hmm sau đó tôi có thể xem xét sử dụng một khung mở rộng Java như Object Team, có khả năng định tuyến lại các cuộc gọi phương thức cụ thể đến các phương thức được xác định của riêng bạn, do đó bạn có thể gõ vào điểm chính xác của luồng điều khiển mà bạn cần thay đổi. hoặc mã của riêng bạn hoặc đối tượng giả mạo của bạn. Nó không quan trọng cho dù đó là một phương pháp công cộng hay riêng tư, ObjecTeams đóng vai trò như một người thay thế cho Java, vì vậy bạn có thể làm những điều Java bình thường sẽ không thể làm được. – micdah

4

Hãy xem jadler (http://jadler.net), thư viện http/thư viện giả mạo tôi đã làm việc một thời gian. Phiên bản ổn định 1.0.0 đã được chỉ phát hành, nó sẽ cung cấp những khả năng mà bạn yêu cầu:

@Test 
public void getAccount() { 

    onRequest() 
     .havingMethodEqualTo("GET") 
     .havingURIEqualTo("/accounts/1") 
     .havingBody(isEmptyOrNullString()) 
     .havingHeaderEqualTo("Accept", "application/json") 
    .respond() 
     .withTimeout(2, SECONDS) 
     .withStatus(200) 
     .withBody("{\"account\":{\"id\" : 1}}") 
     .withEncoding(Charset.forName("UTF-8")) 
     .withContentType("application/json; charset=UTF-8"); 

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port()); 
    final Account account = service.getAccount(1); 

    assertThat(account, is(notNullValue())); 
    assertThat(account.getId(), is(1)); 
} 


@Test 
public void deleteAccount() { 

    onRequest() 
     .havingMethodEqualTo("DELETE") 
     .havingPathEqualTo("/accounts/1") 
    .respond() 
     .withStatus(204); 

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port()); 
    service.deleteAccount(1); 

    verifyThatRequest() 
     .havingMethodEqualTo("DELETE") 
     .havingPathEqualTo("/accounts/1") 
    .receivedOnce(); 
} 
Các vấn đề liên quan