2012-03-14 24 views
6

Bài kiểm tra của tôi tập trung vào một AsyncTask hoàn thành và xác nhận rằng một Hoạt động tiếp theo được bắt đầu.ActivityUnitTestCase và Activity # runOnUiThread

Được biết AsyncTask # onPostExecute không được gọi trừ khi AsyncTask được khởi tạo và thực hiện từ chuỗi giao diện người dùng, vì vậy phương thức của tôi (kiểm tra có thể nhìn thấy) để gọi AsyncTask đi qua các biện pháp phòng ngừa cần thiết để đảm bảo hành vi này - thông qua Runnable mà ngay lập tức chạy nếu trên chuỗi giao diện người dùng hoặc được lên lịch để chạy trên chuỗi giao diện người dùng.

Khi phương thức này được gọi từ một kiểm tra ActivityUnitTestCase, Runnable khởi tạo và thực thi AsyncTask này thông qua Activity # runOnUiThread kết thúc chạy trên một luồng khác với chuỗi giao diện người dùng. Có cách nào để đảm bảo rằng Runnable này sẽ thực thi trên chuỗi giao diện người dùng từ bên trong Hoạt động không?

Addenda:

  • thử nghiệm này chạy như kỳ vọng dưới một lớp ActivityInstrumentationTestCase2, nhưng tôi không có quyền truy cập vào ActivityUnitTestCase # getStartedActivityIntent. Tôi biết về Instrumentation.ActivityMonitor và đó không phải là giải pháp.
  • Runnables được lên lịch trên ActivityUnitTestCase # runTestOnUiThread do chạy trên giao diện người dùng .
  • Tôi không tìm cách xác định lại thử nghiệm của mình.
  • Rất kỳ lạ, ActivityUnitTestCase # startHoạt động cuộc gọi Hoạt động # onTạo NOT trên chuỗi giao diện người dùng.

Edit: Đây là một chút (chưa được kiểm tra) mã đó chứng tỏ bản chất của vấn đề:

// ExampleActivityTests.java 

class ExampleActivityTests : public ActivityUnitTestCase <ExampleActivity> { 

    public void testThatRequiresUiThread() { 

     startActivity (new Intent(), null, null); 
     // ...call instrumentation onStart, onResume... 

     runTestOnUiThread(new Runnable() { 
      public void run() { 
       boolean isUiThread = Thread.currentThread() == Looper.getMainLooper().getThread(); 
       Log.d ("A", "Running on UI Thread? " + isUiThread); 
      } 
     }); 

     getActivity().methodRequiringUiThread(); 

     // assertions here... 
    } 
} 

// ExampleActivity.java -- just the relevant method 

    public void methodRequiringUiThread() { 

     runOnUiThread(new Runnable() { 
      public void run() { 
       boolean isUiThread = Thread.currentThread() == Looper.getMainLooper().getThread(); 
       Log.d ("B", "Running on UI Thread? " + isUiThread); 
      } 
     }); 
    } 

Trong LogCat chúng ta sẽ thấy:

A | Running on UI Thread? true 
B | Running on UI Thread? false 
+1

Một chút bối rối bằng cách đọc báo cáo của bạn _ "thông qua một Runnable đó ngay lập tức chạy nếu trên thread UI hoặc dự kiến ​​sẽ chạy trên thread UI" _, tốt hơn để đính kèm một số đoạn mã để làm rõ vấn đề của bạn. – yorkw

+0

Có lẽ câu lệnh đó đã chi tiết quá trình triển khai thực hiện quá nhiều - mục đích của nó là chỉ đơn thuần là lái xe về nhà mà tôi thực sự đảm bảo rằng AsyncTask được tạo và thực thi trên luồng giao diện người dùng. Tôi có thể thêm mã thể hiện vấn đề tôi đang gặp phải, nhưng tôi sẽ làm như vậy với khía cạnh này bị bỏ qua. – Travis

Trả lời

4

Calling ActivityUnitTestCase # startActivity trên thread UI giải quyết được vấn đề của tôi.

public void testThatRequiresUiThread() { 

    runTestOnUiThread(new Runnable() { 

     @Override 
     public void run() { 
      startActivity(new Intent(), null, null); 
     } 
    }); 

    // ... 
    getActivity().methodRequiringUiThread(); 

    // rest of test... 
} 

mang

A | Running on UI Thread? true 
B | Running on UI Thread? true 
Các vấn đề liên quan