我有Thread
它運行在程序運行和民意測驗隊列,並檢查是否有對象,如果是,那麼它的對象上調用方法如何單元測試線程這需要時間來執行動作
這裏驗證碼:
while(isRunning){
synchronized (loginQueue) {
if(loginQueue.peek() != null) {
Object[] loginObjectWithConnection = loginQueue.poll();
tryLogin(loginObjectWithConnection);
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
這裏是tryLogin方法
private void tryLogin(Object[] loginObjectWithConnection) {
LoginPacket packet = (LoginPacket)loginObjectWithConnection[0];
Connection connection = (Connection)loginObjectWithConnection[1];
try {
if(playerDataService.arevalidCredentials(packet.getUserName(), packet.getPassword())) {
if(!playerDataService.isPlayerBanned(packet.getUserName())){ //Player exists in the system
communicationService.sendTCP(connection, packetFactory.makeLoginFailurePacket(StringConstants.PLAYER_BANNED));
} else{ //Player is not banned
}
} else { // Player does not exist
communicationService.sendTCP(connection, packetFactory.makeLoginFailurePacket(StringConstants.INVALID_USER));
}
} catch (SQLException e) {
communicationService.sendTCP(connection, packetFactory.makeLoginFailurePacket(StringConstants.SERVER_ERROR));
e.printStackTrace();
}
}
現在我的問題是,我要測試的這些服務方法的調用,但是當我運行單元測試他們將無法工作,因爲它需要時間才能達到tryLogin的點,直到那時JUnit失敗。我嘗試使用Thread.sleep()
,但我知道這是不正確的做法,因爲它有時會失敗並且有時會通過。
以下是我在我的單元測試
@Test
public void theExpectedMessageShouldBeSentIfUserIsBanned() throws InterruptedException, SQLException {
//Arrange
when(moqLoginQueue.peek()).thenReturn(object);
when(moqLoginQueue.poll()).thenReturn(object);
LoginFailurePacket packet = new LoginFailurePacket(StringConstants.PLAYER_BANNED);
when(moqPacketFactory.makeLoginFailurePacket(StringConstants.PLAYER_BANNED)).thenReturn(packet);
when(moqPlayerDataService.arevalidCredentials(anyString(), anyString())).thenReturn(true);
when(moqPlayerDataService.isPlayerBanned(anyString())).thenReturn(true);
//Act
loginManager.start();
Thread.sleep(10); //Dirty hack -.-
//Assert
verify(moqCommunicationService).sendTCP(any(Connection.class), eq(packet));
}
對於在服務器上接收到的每個登錄請求,您都希望我在run方法內創建Authentication類的對象,並且還可以將Runnable提交給ExecutorService,而不是輪詢隊列? – Sneh
準確。它更簡單,更高效 – Raffaele