2016-11-17 62 views
3

現在我嘗試使用JUnit4測試它,但我正在逐漸如何在Android上測試Firebase任務?

java.lang.IllegalStateException: 
    Must not be called on the main application thread 

at com.google.android.gms.common.internal.zzab.zzhj(Unknown Source) 
at com.google.android.gms.common.internal.zzab.zzate(Unknown Source) 
at com.google.android.gms.tasks.Tasks.await(Unknown Source) 
at com.example.tasks.GetUserProfileTest.then(GetUserProfileTest.java:18) 
    <27 internal calls> 

Process finished with exit code 255 

我創建了一個Continuation任務上Firebase Realtime Database執行操作。

public class GetUserProfile implements Continuation<String, Task<Profile>>, 
     ValueEventListener { 

    private TaskCompletionSource<Profile> mTaskCompletionSource; 
    private DatabaseReference mDatabase; 

    public GetUserProfile() { 
     mTaskCompletionSource = new TaskCompletionSource(); 
     mDatabase = FirebaseDatabase.getInstance().getReference(); 
    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) { 
     mDatabase.removeEventListener(this); 
     mTaskCompletionSource.setException(databaseError.toException()); 
    } 

    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     mDatabase.removeEventListener(this); 
     mTaskCompletionSource.setResult(dataSnapshot.getValue(Profile.class)); 
    } 

    @Override 
    public Task<Profile> then(Task<String> task) { 
     mDatabase.child(task.getResult()).addValueEventListener(this); 
     return mTaskCompletionSource.getTask(); 
    } 
} 

和單元測試吧:

public class GetUserProfileTest { 
    @Test 
    public void then() throws Exception { 
     Task<Profile> task = Tasks.<String>forResult("17354686546") 
      .continueWithTask(new GetUserProfile()); 

     try { 
      Profile profile = Tasks.await(task); 
      assertEquals(profile.getEmail(), "[email protected]"); 
     } catch (ExecutionException e) { 
      fail(e.getMessage()); 
     } catch (InterruptedException e) { 
      fail(e.getMessage()); 
     } 
    } 
} 

是否存在的測試任務,而無需使用handlersCountDownLatch一個簡單的方法?

+0

究竟是哪一行導致錯誤,它的完整堆棧跟蹤是什麼? –

+0

'Tasks.await'因爲它阻塞了主線程。我知道這可以使用'CountDownLatch'來完成,但我正在跳躍尋找更優雅的解決方案。 –

+1

我只是直接調用Continuation上的'then'方法。另外,要成爲一個真正的單元測試,我會完全嘲笑數據庫,並檢查它是否被正確查詢。但是如果一個單元測試真的必須測試線程(最好不要),那麼CDL就是要走的路。 –

回答

0
public class GetUserProfileTest { 
    @Test 
    public void then() throws Exception { 
     try { 
      Task<String> previousTask = Tasks.forResult("17354686546"); 
      GetUserProfile continuation = new GetUserProfile(); 
      Profile profile = continuation 
        .then(previousTask) 
        .getResult(); 

      assertEquals(profile.getEmail(), "[email protected]"); 
     } catch (ExecutionException e) { 
      fail(e.getMessage()); 
     } catch (InterruptedException e) { 
      fail(e.getMessage()); 
     } 
    } 
}