如何在Spring中模拟对Rest请求的超时响应?

huangapple go评论77阅读模式
英文:

How to simulate timeout in response to a Rest request in Spring?

问题

我有一个使用Spring Boot 2实现的Rest API。为了在超时时检查一些客户端行为,我该如何在测试环境中模拟这种情况呢?服务器应该定期接收并处理请求(实际上,在生产环境中,由于随机网络减速和大量响应数据,会出现超时)。

是否将长时间的休眠添加为适当的模拟技术?是否有任何更好的方法来真正使服务器“丢弃”响应?

英文:

I have a Rest API implemented with Spring Boot 2. To check some client behavior on timeout, how can I simulate that condition in my testing environment? The server should regularly receive the request and process it (in fact, in production timeouts happen due to random network slowdowns and large big response payloads).

Would adding a long sleep be the proper simulation technique? Is there any better method to really have the server "drop" the response?

答案1

得分: 1

需要睡眠来测试代码被认为是不良实践。相反,您希望复制从超时接收到的异常,例如在使用 RestTemplate.exchange 时出现的 java.net.SocketTimeoutException

然后,您可以编写如下的测试代码:

public class FooTest

    @Mock
    RestTemplate restTemplate;

    @Before
    public void setup(){
        when(restTemplate.exchange(...)).thenThrow(new java.net.SocketTimeoutException())
    }

    @Test
    public void test(){
        // 待办事项
    }

}

这样,您就不必无聊地等待某些事情发生了。

英文:

Needing sleeps to test your code is considered bad practice. Instead you want to replicate the exception you receive from the timeout, e.g. java.net.SocketTimeoutException when using RestTemplate.exchange.

Then you can write a test as such:

public class FooTest

    @Mock
    RestTemplate restTemplate;

    @Before
    public void setup(){
        when(restTemplate.exchange(...)).thenThrow(new java.net.SocketTimeoutException())
    }

    @Test
    public void test(){
        // TODO
    }

}

That way you wont be twiddling your thumbs waiting for something to happen.

答案2

得分: 0

睡眠是一种方法,但如果您像那样编写了几十个测试,那么必须等待睡眠会导致测试套件运行时间非常长。

另一种选择是在客户端测试中更改超时的“阈值”。如果在生产环境中,您的客户端需要等待5秒钟才能收到响应,那么在测试中将其更改为0.5秒(假设您的服务器响应时间超过这个时间),但保持相同的错误处理逻辑。

后一种方法可能不适用于所有情况,但肯定能避免您的测试套件运行时间超过10分钟。

英文:

Sleep is one way to do it, but if you're writing dozens of tests like that then having to wait for a sleep will create a really long-running test suite.

The alternative would be to change the 'threshold' for timeout on the client side for testing. If in production your client is supposed to wait 5 seconds for a response, then in test change it to 0.5 seconds (assuming your server takes longer than that to respond) but keeping the same error handling logic.

The latter might not work in all scenarios, but it will definitely save you from having a test suite that takes 10+ mins to run.

答案3

得分: 0

你可以做一件与我在我的情况下所做的一样的事情。
实际上在我的情况下,当我的应用程序在生产环境中运行时,我们会不断地从API中轮询交易,有时它会通过抛出异常SSLProtocolException来中断连接。

我们所做的是

int retryCount = 5; 
while (true) { 
    count++;
    try { 
        //在这里发送API请求
    } catch (Exception e) {
         if (retryCount == count) {
            throw e
            // 在这里我们可以进行线程休眠,然后在一段时间后尝试重新连接
         }
    }
}

类似地,在你的情况下,它会抛出一些异常,捕获那个异常,然后将你的线程休眠一段时间,然后再次尝试连接。你可以根据自己的需求修改retryCount,在我这个案例中是5。

英文:

You can do one thing which I did in my case .
Actually in my case, when my application is running in a production environment, we keep on polling trades from the API and sometimes it drops the connection by throwing an Exception SSLProtocolException.

What we did

int retryCount =5; 
while (true ){ 
    count++;
    try{ 
        //send an api request here
    }catch (Exception e){
         if(retryCount == count ) {
            throw e
            // here we can do a thread sleep. and try after that period to reconnect 
         }
    }
}

Similarly in your case some Exception it will throw catch that Exception and put your thread in Sleep for a while and after that again try for Connection the retryCount you can modify as per your requirment, in my case it was 5.

huangapple
  • 本文由 发表于 2020年8月31日 23:40:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63673904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定