我正在尝试使用java.net.http.HttpClient
API为我在Java11中创建的服务创建一些单元测试。代码工作正常,但在运行单元测试时出现java.lang.reflect.InaccessibleObjectException
错误。
服务类:
@Stateless
public class MyWebService {
@Inject
private HttpClient httpClient;
public void makeHttpCall(){
final HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://someurl.com"))
.headers(CONTENT_TYPE, "application/json")
.GET()
.build();
final HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// business logic
}
}
测试类如下:
@RunWith(MockitoJUnitRunner.class)
public class MyWebServiceTest {
@InjectMocks
private MyWebService service;
@Mock
private HttpClient httpClient;
@Test
public void shouldMakeHttpCallTest(){
service.makeHttpCall();
//asserts
}
}
我做错了什么吗?我看到很多人在方法本身中示例化了一个新的httpClient示例,但是,我不确定这样是否可测试。
我想达到的效果是
@RunWith(MockitoJUnitRunner.class)
public class JdkHttpClientServiceShould {
@InjectMocks
private JdkHttpClientService victim;
@Mock
private HttpClient httpClient;
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void executeRequest() throws Exception {
HttpResponse httpResponse = mock(HttpResponse.class);
when(httpClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(httpResponse);
when(httpResponse.statusCode()).thenReturn(200);
when(httpResponse.body()).thenReturn("Hello");
ArgumentCaptor<HttpRequest> httpRequestArgumentCaptor = ArgumentCaptor.forClass(HttpRequest.class);
ArgumentCaptor<HttpResponse.BodyHandler<String>> bodyHandlerArgumentCaptor = ArgumentCaptor.forClass(HttpResponse.BodyHandler.class);
ClientResponse clientResponse = victim.executeRequest(HTTP_URL);
assertThat(clientResponse.getStatusCode()).isEqualTo(200);
assertThat(clientResponse.getResponseBody()).isEqualTo("Hello");
verify(httpClient, times(1)).send(httpRequestArgumentCaptor.capture(), bodyHandlerArgumentCaptor.capture());
assertThat(httpRequestArgumentCaptor.getValue().uri().toString()).isEqualTo(HTTP_URL);
assertThat(httpRequestArgumentCaptor.getValue().method()).isEqualTo(GET_METHOD);
assertThat(httpRequestArgumentCaptor.getValue().headers().map()).containsExactly(Assertions.entry(HEADER_KEY_CLIENT_TYPE, Collections.singletonList(JDK_HTTP_CLIENT.getValue())));
assertThat(bodyHandlerArgumentCaptor.getValue()).isEqualTo(HttpResponse.BodyHandlers.ofString());
}
}
任何帮助都是最好的谢谢
完整堆栈跟踪为:
java.lang.reflect.InaccessibleObjectException: Unable to make protected java.net.http.HttpClient() accessible: module java.net.http does not "opens java.net.http" to unnamed module @595b007d
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:189)
at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:182)
at org.mockito.internal.creation.cglib.ClassImposterizer.setConstructorsAccessible(ClassImposterizer.java:86)
at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:56)
at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
at org.mockito.Mockito.mock(Mockito.java:1285)
at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:33)
at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
at org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:43)
at org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:66)
at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:71)
at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:55)
at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:319)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
2条答案
按热度按时间tjrkku2a1#
使用mockito @Spy
r8xiu3jd2#
这是因为
HttpClient
是一个抽象类。您应该使用CALLS_REAL_METHODS
标记或模拟实现来模拟抽象类。Here就是一个例子。
或者,您可以使用
WireMock
来模拟您调用的端点。Here示例