2014-08-28 22 views
7

Tôi đang cố gắng viết một bài kiểm tra đơn vị cho một đoạn mã với robolectric. Vấn đề là tôi cần phải giả cuộc gọi http nhưng dường như lớp giả của robolectric rằng nó chỉ làm việc với HttpClient của Apache như mỗi câu trả lời này:Robolectric + OkHttp + trang bị thêm + rxJava Kiểm tra Đơn vị

Link to answer

Trong Retrofit bạn không thể thay đổi URL nên MockWebServer dường không phải là một lựa chọn.

Có vẻ như mockito có thể bắt được các cuộc gọi lại trang bị thêm nhưng tôi đang sử dụng rxJava vì vậy tôi không thực sự biết nếu nó có thể giúp.

Có ai có bất kỳ đề xuất nào về thử nghiệm đơn vị với Robolectric + Retrofit + okHttp + rxJava không?

Đây là một đoạn mã nhỏ:

@Test 
public void test1() throws IOException, InterruptedException { 
    FragmentA frag = (FragmentA) activity 
      .getFragmentManager().findFragmentById(
        R.id.frag); 
    assertThat(frag).isNotNull(); 
    assertThat(frag.isVisible()).isTrue(); 

    EditText input1 = (EditText) frag.getView() 
      .findViewById(R.id.edit_text1); 
    EditText input2 = (EditText) frag.getView() 
      .findViewById(R.id.edit_text2); 
    Button button = (button) frag.getView() 
      .findViewById(R.id.button); 
    input1.setText("999"); 
    input2.setText("999"); 
    Robolectric.addPendingHttpResponse(200, "{\"isValid\": true}"); 
    button.performClick(); 
      assertThat(
      ShadowAlertDialog.getLatestDialog() instanceof ProgressDialog) 
      .isTrue(); 

    } 

Robolectric.addPendingHttpResponse sẽ không hoạt động nào vì OkHttp. Cuộc gọi api được bắt đầu khi nút được nhấn để trong thời điểm đó, tôi cần giả mạo phản hồi!

Trả lời

0

Tại sao bạn không thể thay đổi url trong trang bị thêm?

RestAdapter restAdapter = new RestAdapter.Builder() 
    .setEndpoint("https://api.github.com") 
    .build(); 

Bạn có thể đặt url từ MockWebServer:

MockWebServer server = new MockWebServer(); 
URL url = server.getUrl("/"); 
+0

Tôi không thể làm điều đó bởi vì RestAdapter là một phần của phần mở rộng của tôi về lớp ứng dụng. Vì vậy, trong phương pháp setUp tôi chỉ tạo ra các hoạt động mà cũng tạo ra các ứng dụng và lớp ứng dụng có chứa RestAdapter với url mặc định của dịch vụ api của tôi. Tôi có thể thêm một phương thức công khai vào lớp ứng dụng cho phép tôi thay đổi RestAdapter sau nhưng điều đó có nghĩa là chỉ thêm mã cho mục đích thử nghiệm và nó sai! – fedestylah

+0

Vâng, nó là sai. Chúng tôi luôn có cùng một vấn đề khi tạo mocks. Sau khi đọc rất nhiều, một giải pháp để tạo ra mocks là tạo ra các nhà máy để tiêm phụ thuộc. Vì vậy, bạn sẽ thay đổi mã của bạn để tạo ra các nhà máy và không cho mục đích thử nghiệm (nếu bạn muốn xem nó theo cách đó: P) – mromer

+0

nhưng dù sao bạn đang làm một số công việc mà bạn sẽ không làm !!:) I Nếu tôi không tìm thấy một cách tiếp cận tốt hơn, tôi sẽ cố gắng theo cách của bạn. Bạn có bất kỳ liên kết hoặc ví dụ, nơi là exaplained cách tiếp cận nhà máy? bởi vì tôi không phải là tâm sự với các nhà máy. cảm ơn! – fedestylah

1

Bạn có thể lấy URL của máy chủ từ một hằng số được khai báo trong build.gradle và thêm một hương vị thử nghiệm hoặc buildType đó ghi đè lên nó

release { 
    buildConfigField "String", "SERVER_URL", "\"github.com\"" 
} 
testing { 
    buildConfigField "String", "SERVER_URL", "\"127.0.0.1\"" 
} 

Một số khác thay thế không phải là Android cụ thể, (IMHO ít thanh lịch hơn nhưng nó hoạt động trong mọi trường hợp) là sử dụng một biến riêng mà chỉ truy cập và sử dụng được trong thử nghiệm, sử dụng phản ánh như thế này:

  1. Tạo một biến tĩnh tin rằng là null, ví dụ: private static Chuỗi BASE_URL = null;
  2. Sử dụng phương pháp để nhận URL máy chủ và phương pháp đó kiểm tra xem có sử dụng BASE_URL khi không rỗng (không bao giờ trong phiên bản phát hành) hay URL từ tài nguyên (không bao giờ mã hóa URL trong mã)
  3. Trong khi thử nghiệm, hãy sử dụng phản ánh để thay đổi chế độ hiển thị riêng tư thành công khai và sửa đổi BASE_URL thành URL thử nghiệm của bạn.

Để làm sự phản ánh một phần sử dụng ví dụ này:

final Field urlField = MyService.class.getDeclaredField("BASE_URL"); 
urlField.setAccessible(true); 
urlField.set(null, TEST_URL); 
Các vấn đề liên quan