2013-07-16 141 views
2

我正在編寫一個Api,在工作線程上執行HTTP請求,然後在完成時調用Callback-Handler的方法。單元測試多線程Api

public class GriklyClient <E,T>{ 

private final IHttpRequest<E,T> request; 
private final ResponseListener<T> response; 


protected GriklyClient (IHttpRequest<E,T> request,ResponseListener<T> response) 
{ 
    this.request = request; 
    this.response = response; 
} 



/** 
* Dispatch a thread to process 
* HTTP Request. 
*/ 
public void execute() 
{ 
    Runnable thread = new Runnable() 
    { 

     public void run() 
     { 
      T result = (T) request.execute(); 
      response.response(result); 
     } 
    }; 
    new Thread(thread).start(); 
}//end execute method 

} 

這是對API的調用的模樣:

Grikly grikly = new Grikly(developerKey); 
grikly.addValidUserCredential(email,password); 
grikly.fetchUser(1, new ResponseListener<User>() { 
     public void response(User result) { 
      // TODO Auto-generated method stub 
      System.out.println(result); 
     } 
    }); 

我遇到的問題是單元測試。我的單元測試中沒有調用回調處理程序,因此即使它們應該失敗,我的測試也始終通過。

private Grikly grikly = new Grikly (developerKey); 
    @Test 
public void fetchUser() 
{ 
    grikly.fetchUser(1, new ResponseListener<User>() { 

     public void response(User result) { 
      Assert.assertNotNull(result); 

     } 
    }); 
}//end fetchUser Test 

如何編寫單元測試來測試此Api?

回答

1

嗯,我猜你在這裏的問題是因爲你的方法fetchUser是一個asynchonous method而不是一個同步的,它將不會返回,直到它完成其工作。

因此,grikly.fetchUser(...的調用將立即返回(測試方法fetchUser()沒有任何失敗或成功的跡象),而您在GriklyClient中創建的'寂寞'線程將繼續運行並通過調用完成其作業您的new ResponseListener<User>中的回調方法response,當然,當時沒有人關心。

IMO,或者CountdownLatch或更通用的ReentrantLock與其Condition好友可以節省您的一天。有關這兩種工具的教程可以通過Google輕鬆找到。祝你好運。

編輯:
第二個想法是,如果您想測試傳遞給回調方法的結果,可能需要將它從您創建的新線程傳遞(或發佈)到測試主線程(通過將其保存到鎖定防護或揮發性裝飾字段)並在@Test註釋的方法中進行測試,您的情況爲fetchUser()