2012-08-12 47 views
6

Tôi mới tham gia thử nghiệm Android, tôi muốn thử nghiệm IntentService và tôi hiện đang mở rộng ServiceTestCase.cách JUnit kiểm tra IntentService

Tôi đang cố gắng sử dụng ResultReceiver nhưng vấn đề là OnReceiveResult không bao giờ được gọi trong trường hợp thử nghiệm. (Tôi cũng đã cố gắng tạo ra ResultReceiver với new Handler() như insetad đối số của null nhưng với kết quả tương tự.

những gì tôi làm sai? cách thích hợp để kiểm tra một IntentService?

đây là dịch vụ là gì :

public class MyService extends IntentService { 

public MyService() { 
    super("MyService"); 
} 

public MyService(String name) { 
    super(name); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 
    final int action = intent.getIntExtra("action", 0); 
    final int request = intent.getIntExtra("request", 0); 
    final ResultReceiver receiver = (ResultReceiver) intent.getExtras().get("receiver"); 

    if (receiver == null) { 
     return; 
    } 

    if (action == 0 || request == 0) { 
     receiver.send(0, null); 

     return; 
    } 
} 

}

và đây là thử nghiệm:

public void testHandleInvalidRequests() { 
    ResultReceiver receiver = new ResultReceiver(null) { 
     @Override 
     protected void onReceiveResult(int resultCode, Bundle resultData) { 
      fail(); 
     } 
    }; 

    Intent intent = new Intent(mContext, MyService.class); 
    intent.putExtra("receiver", receiver); 
    startService(intent); 

} 

Trả lời

4

Tôi đã thành công trong việc kiểm tra IntentService và tôi sẽ cho bạn thấy khái niệm về cách tôi đã làm điều đó.

Trước tiên, bạn mở rộng lớp Kiểm tra dịch vụ Android: ServiceTestCase<MyIntentService>. Sau đó, bạn về cơ bản bắt đầu IntentService như bạn đã sử dụng startService(intent).

Vì dịch vụ được thử nghiệm là IntentService, nó sẽ làm tất cả công việc trong chuỗi công nhân sinh ra. Nếu bạn không chặn chủ đề thử nghiệm của bạn thì phương pháp thử nghiệm của bạn sẽ ngay lập tức xác nhận rằng rõ ràng là sẽ thất bại vì công việc thử nghiệm trong nền có thể chưa hoàn thành. Cuối cùng, phương pháp kiểm tra sẽ trở lại và thử nghiệm của bạn sẽ thất bại.

Điều bạn cần làm là chặn chuỗi thử nghiệm sau startService. Thực hiện việc này bằng cách sử dụng số ReentrantLock và Điều kiện gọi số await() trên đó.

IntentService sau đó thực hiện onHandleIntent ở chế độ nền. Tôi đề nghị bạn mở rộng IntentService và ghi đè onHandleIntent, gọi super.onHandleIntent() và sau đó, báo hiệu chuỗi thử nghiệm của bạn rằng công việc đã được thực hiện. Làm điều này trên cùng một khóa và điều kiện được sử dụng để chặn chuỗi thử nghiệm.

+1

Bạn có thể cho một ví dụ của việc sử dụng ReentrantLock đây? –

+0

Tôi cũng sẽ rất quan tâm đến một ví dụ (thậm chí hai năm sau). Cảm ơn bạn. – JDenais

+0

Hi, bất kỳ bối cảnh tôi được sử dụng để khởi tạo Intent dường như ném một ngoại lệ con trỏ null. Bạn đã thiết lập bối cảnh của mình như thế nào? – kyrax

0

Nếu startService() trong file thử nghiệm kéo dài ServiceTestCase<>, tôi đã tìm thấy trong cơ sở thử nghiệm Android Studio 1.1 rằng ServiceTestCase không nhanh chóng một đối tượng IntentService qua onHandleIntent().
Xem Android ServiceTestCase for IntentService để biết thêm thông tin.

0

Tôi biết điều này là cũ, nhưng vì tôi đã có cùng một loại vấn đề, tôi sẽ đăng bài ở đây cách cuối cùng tôi đã quản lý để chạy thử nghiệm trên IntentService. Như @ Joerg nói, đó là một vấn đề luồng.

public class MyServiceTest extends ServiceTestCase<MyService> { 
    public MyServiceTest() { 
     super(MyService.class); 
    } 

    public void testOnHandleIntent() throws Exception { 
     Looper.prepare(); 
     final CountDownLatch latch = new CountDownLatch(1); 

     ResultReceiver receiver = new ResultReceiver(new Handler()) { 
      @Override 
      protected void onReceiveResult(int resultCode, Bundle resultData) { 
       latch.countDown(); 

       assertEquals(resultCode, 0); 
       assertNull(resultData); 
       fail(); 

       Looper.myLooper().quit(); 
      } 
     }; 

     Intent intent = new Intent(getSystemContext(), MyService.class); 
     intent.putExtra("receiver", receiver); 
     getSystemContext().startService(intent); 

     Looper.loop(); 

     assertThat(latch.getCount(), is(0L)); 
    } 
} 

Các LooperHandler lớp là cần thiết để gọi lại có một sợi được gọi vào. Các chốt là chỉ có như là một ví dụ về một khóa và như một phương tiện để khẳng định rằng các mã thông qua các cuộc gọi lại trước khi kết thúc của phương pháp thử nghiệm.

Nếu phương pháp quit() của Looper không được gọi, kiểm tra bị treo.

ServiceTestCase bị phản đối trên các phiên bản mới nhất của Android, nhưng sự thay thế (ServiceTestRule) không hỗ trợ IntentService ...

Các vấn đề liên quan