gpt4 book ai didi

java:在调度程序内对 lambda 表达式进行单元测试

转载 作者:行者123 更新时间:2023-12-02 00:20:54 25 4
gpt4 key购买 nike

我有一个类:

public class RequestHandler implements HttpHandler {
public void handleRequest(HttpServerExchange serverContext) throws Exception {
serverContext.dispatch(() -> serverContext.getRequestReceiver()
.receiveFullBytes((httpServerExchange, reqBytes) -> {

// business logic along with few function call

}
)
);

}
}

我想编写一个单元测试用例来测试我的业务逻辑。我不知道如何在调度程序内使用 2 个级别的 lambda 表达式来做到这一点?有人可以建议一种编写测试用例的好方法吗?

我知道我们可以将业务逻辑移至新类并可以测试它(我猜它设计得更好),但很想知道如果它是某些遗留代码的一部分或我们无法更改的东西,我们如何测试是吗?

最佳答案

假设您在业务逻辑中的某个位置将收到的消息(或您对其执行的任何操作)转发到其他地方,您可以像往常一样测试您的代码。

请注意,HttpServerExchange 是一个最终类,因此您需要使用支持 final 模拟的 Mockito 版本 - 并且必须启用它,如所述 here .

要绕过 lambda 表达式,您需要使用 thenAnswerdoAnswer手动触发正确接口(interface)方法的调用。

一个简单的例子如下所示:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;

import io.undertow.io.Receiver;
import io.undertow.io.Receiver.FullBytesCallback;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;

@ExtendWith(MockitoExtension.class)
public class RequestHandlerTest {

static class BuisnessLogic {
public void someMethod(HttpServerExchange httpServerExchange, byte[] reqBytes) {
}
}

static class RequestHandler implements HttpHandler {

BuisnessLogic logic;

public void handleRequest(HttpServerExchange serverContext) throws Exception {
serverContext.dispatch(
() -> serverContext.getRequestReceiver().receiveFullBytes(
(httpServerExchange, reqBytes) -> {
logic.someMethod(httpServerExchange, reqBytes);
}
)
);
}
}

@Mock
BuisnessLogic logic;

@InjectMocks
RequestHandler handler;

@Test
public void test() throws Exception {

byte[] message = new byte[] {1,2,3};
HttpServerExchange serverContext = Mockito.mock(HttpServerExchange.class);

// 1st lambda
Mockito.when(serverContext.dispatch(Mockito.any(Runnable.class)))
.thenAnswer((Answer<HttpServerExchange>) invocation -> {

Runnable runnable = invocation.getArgument(0);
runnable.run();

return serverContext;
});

// 2nd lambda
Receiver receiver = Mockito.mock(Receiver.class);
Mockito.doAnswer((Answer<Void>) invocation -> {

FullBytesCallback callback = invocation.getArgument(0);
callback.handle(serverContext, message);

return null;

}).when(receiver).receiveFullBytes(Mockito.any(FullBytesCallback.class));

Mockito.when(serverContext.getRequestReceiver()).thenReturn(receiver);

// class under test - method invocation
handler.handleRequest(serverContext);

// buisness logic call verification
ArgumentCaptor<HttpServerExchange> captor1 = ArgumentCaptor.forClass(HttpServerExchange.class);
ArgumentCaptor<byte[]> captor2 = ArgumentCaptor.forClass(byte[].class);

Mockito.verify(logic).someMethod(captor1.capture(), captor2.capture());

Assertions.assertEquals(serverContext, captor1.getValue());
Assertions.assertEquals(message, captor2.getValue());
}
}
<小时/>

正如其他人已经提到的,您应该只对遗留代码使用这种方法。

简单的重构可以将您需要测试的整个部分插入其自己的方法中,在上面的示例中,该方法只是业务逻辑本身。

没有明确需要亲自测试 undertow 框架。

关于java:在调度程序内对 lambda 表达式进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58077230/

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