【发布时间】:2021-05-11 12:55:48
【问题描述】:
您好,不知道是否有人可以帮助我。我正在尝试为使用 java.net.http.HttpClient API 在 Java 11 中创建的服务创建一些单元测试。 代码运行良好,但运行单元测试时出现 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)
公共类 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)
【问题讨论】:
-
您使用的是哪个版本的
mockito?确保它与 Java-11 兼容? -
JUnit 4.13 将尝试更新
-
问题是我的 mockito 版本太旧了。升级它解决了这个问题。谢谢