4

Android 프로젝트에 대해 매우 간단한 단위 테스트 케이스를 작성 중이므로 테스트 케이스는 백그라운드에서 네트워크 작업을 수행하는 AsyncTask을 간단히 실행합니다. 내 테스트 케이스에 대한 AndroidTestCase 클래스를 확장하고있다 :AndroidTestCase에서 AsyncTask의 onPostExecute()가 결코 호출되지 않습니다.

public class MyTest extends AndroidTestCase{ 
    //use CountDownLatch to perform wait-notify behavior 
    private CountDownLatch signal; 
    @Override 
    public void setUp() throws Exception{ 
    super.setUp(); 
    //I use CountDownLatch to perform wait-notify behaviour 
    signal = new CountDownLatch(1); 
    } 

    @Override 
    public void runTest() throws Exception{ 
     String params = "some params"; 
     //MyAsyncTask does the networking tasks 
     new MyAsyncTask().execute(params); 

     //wait until MyAsyncTask is done 
     try { 
     signal.await(); 
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } 

    } 

    private class MyAsyncTask extends AsyncTask<String, Void, String>{ 

    @Override 
    protected String doInBackground(String... params) { 
      //Do networking task e.g. access a remote database 
    } 

    @Override 
    protected void onPostExecute(String result){ 
     super.onPostExecute(result); 
      //this never get called when run this test case, why? 
      Log.i("Debug","post execute");  
      signal.countDown(); 
    } 
    } 
} 

위에서 볼 때, 나는 동작을 대기 통지 수행 할 CountDownLatch을 사용하고 있습니다.

MyAsicTask 후 시작, 내가 signal.await()에 호출 완료 MyAsyncTask에 대한을 기다립니다.

MyAsyncTaskonPostExecute() 콜백, 나는 signal.countDown()에이 작업이 이루어집니다 통지 호출합니다.

그러나이 테스트 케이스를 실행하면 onPostExecute은 호출되지 않습니다. & 해결 방법은 무엇입니까?

내가 runTest()의 마지막 라인으로 Thread.sleep(30*1000)을 추가

후 ======== 업데이트 ==========, 내가 네트워크 운영에서 더 많은 로그를 볼 수 있습니다. 네트워크 작동이 완료되기 전에 teardown()이 호출됨을 증명합니다. 나는 tearDown(), android 테스트 프레임 워크에서 아무것도하지 않았다. 자동으로 호출합니다.

보냄을 사용하여 CountDownLatch이 작동하지 않습니다 ... 이유가 무엇입니까?

+1

doInBackground의 예외는 무엇입니까? – Triode

+0

'doInBackground'에서 뭔가 잘못되어'onPostExecute'가 호출을받지 못합니다. – d3m0li5h3r

+0

@ d3m0li5h3r doInbackground()가 충돌하여 비동기 작업을 취소하지 않으면 onPostExecute()가 실행되지 않습니다. –

답변

0

네트워크 작업이 매우 시간이 오래 걸리므로 오랜 시간이 걸리므로 onPostExecute() 메소드를 호출 할 수없는 이유는 무엇입니까?

+0

안드로이드는 메인 스레드 (UI 스레드)에 네트워크 작업을 허용하지 않기 때문에 백그라운드 스레드에 넣어야합니다. – Mellon

1

나는 동일한 문제가 있었기 때문에 ... 여기 나를 위해 그것을 해결 한 것이있다. 클래스를 AndroidTestCase로 확장하는 대신 InstrumentationTestCase를 확장하도록합니다.

그런 다음 나는이 같은 AsyncTask를 시작 :

runTestOnUiThread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      startAsyncTask(); 
     } 
    }); 
0

는 doInBackground 방법은 이유는이 문제가되지 않습니다 있는지 확인하십시오. 이 샘플 태스크를 시도하십시오. 그리고 결과를 공유하십시오.

private class MyAsyncTask extends AsyncTask<String, Void, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     Log.i("Debug", "onPreExecute"); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     Log.i("Debug", "doInBackground"); 
     return "operation finished"; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     Log.i("Debug", "onPostExecute"); 
     signal.countDown(); 
    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
     Log.i("Debug", "onCancelled"); 
    } 
} 

편집 : 나는 AndroidTestCase들과 AsyncTask들과 함께 작업하는 동안 문제가있을 수 있습니다 궁금. 방금 코드를 프로젝트에 복사하고 AsyncTask으로 테스트했습니다 (위의 작업 참조). doInBackground 이후의 모든 실행에서 onPostExecute 메서드가 성공적으로 호출됩니다. 나는 수면 시간이 2 분인 장기 실행 작업을 시뮬레이션했으며, 이는 또한 onPostExecute 방법으로 입력되었습니다. onPostExecute 다음에 tearDown 메서드가 호출됩니다.

따라서 여기의 문제는 doInBackground 방법 내부의 루프 일 것입니다. 또는 어떻게 든 취소되고 작업의 onCancelled 메서드가 호출됩니다.

0

onPostExecute()은 호출자 스레드 execute()에서 실행되어야합니다. 해당 스레드가 signal.await()과 같은 호출을 통해 일시 중지되면 onPostExecute()을 실행할 수 없습니다. 따라서 execute()으로 전화 한 후 signal.await()을 가질 수 없습니다.

관련 문제