gpt4 book ai didi

java - 如何对需要时间执行操作的线程进行单元测试

转载 作者:行者123 更新时间:2023-11-30 10:55:10 26 4
gpt4 key购买 nike

我有 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));
}

最佳答案

该系统在当前形式下是不可测试的:良好的测试质量包括:

  • 易于其他程序员理解
  • 其他程序员很难破解
  • 跑得快

您要测试的逻辑片段是 LoginManager.tryLogin,它在您的代码段中是私有(private)的。如果您想公开记录它(测试是一种文档:它们说明系统应该如何运行),它必须是公开的。

我建议将所有逻辑移至新类中的方法:Authentication.attempt()(我建议使用不可变对象(immutable对象)和不带任何参数的方法 - 有人说最佳OO 设计中的参数数量为零)。

既然测试是可行的,我还认为您应该摆脱 LoginManager.start() 中的所有代码:只需使用 ExecutorService 并提交身份验证尝试 -这样您将拥有更快的程序和更少的测试代码,因为困难(和棘手)的部分由 Java 管理。

关于java - 如何对需要时间执行操作的线程进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33426494/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com