无法使用 PowerMockito 模拟某些最终 类 - java.lang.IllegalAccessError
Unable to mock certain final classes with PowerMockito - java.lang.IllegalAccessError
当我尝试从某个 Google 库中模拟某些最终的 class 时,例如 SearchGoogleAdsRequest
他们给我 IllegalAccessError
,我添加了 @PrepareForTest
class.
顶部的注释
@RunWith(PowerMockRunner.class)
@PrepareForTest({SearchGoogleAdsRequest.class})
@PowerMockIgnore({"javax.net.ssl.*"})
public class GoogleAdsReportDownloaderTest {
final SearchGoogleAdsRequest searchGoogleAdsRequest = PowerMockito.mock(SearchGoogleAdsRequest.class);
final GoogleAdsServiceClient mockGoogleAdsServiceClient = mock(GoogleAdsServiceClient.class);
final GoogleAdsServiceClient.SearchPagedResponse searchPagedResponse =
mock(GoogleAdsServiceClient.SearchPagedResponse.class);
when(mockGoogleAdsServiceClient.searchPagedCallable()).thenReturn(callable);
when(mockGoogleAdsServiceClient.searchPagedCallable().call(searchGoogleAdsRequest)).thenReturn(searchPagedResponse);
when(searchPagedResponse.iterateAll()).thenReturn(Arrays.asList(mockGoogleAdsRow));
when(mockGoogleAdsServiceClient.search(any())).thenReturn(searchPagedResponse);
错误
java.lang.IllegalAccessError: Class com/google/ads/googleads/v6/services/SearchGoogleAdsRequest$MockitoMock53664588 illegally accessing "package private" member of class com/google/protobuf/GeneratedMessageV3$UnusedPrivateParameter
SearchGoogleAdsRequest
final class 看起来像这样,PowerMockito 无法模拟。
public final class SearchGoogleAdsRequest extends GeneratedMessageV3 implements SearchGoogleAdsRequestOrBuilder {
private static final SearchGoogleAdsRequest DEFAULT_INSTANCE = new SearchGoogleAdsRequest();
private static final Parser<SearchGoogleAdsRequest> PARSER = new AbstractParser<SearchGoogleAdsRequest>() {
public SearchGoogleAdsRequest parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException {
return new SearchGoogleAdsRequest(input, extensionRegistry);
}
};
private SearchGoogleAdsRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
this.memoizedIsInitialized = -1;
}
private SearchGoogleAdsRequest() {
this.memoizedIsInitialized = -1;
this.customerId_ = "";
this.query_ = "";
this.pageToken_ = "";
this.summaryRowSetting_ = 0;
}
我可以通过配置 MockMaker 来绕过这个。但是 MockMaker 不能与 PowerMockito 一起工作并给出错误(无法初始化插件,并且某些加载程序应该与 Mockito 一起使用但正在与 PowerMockito 一起加载)。
我需要使用 Power Mockito,因为我需要模拟本地范围对象,而其他人创建的其他单元测试与 MockMaker 不兼容。
我使用 newBuilder 创建 class 的对象解决了这个问题并绕过了这个问题。它并没有真正模拟 class,但在我的情况下我可以将其用作我需要模拟的 class 的参数。如果我们不需要 PowerMockito,那么我们可以将 Mockito 与 MockMaker 一起使用,但是这些 classes 可以很容易地被模拟。
final SearchGoogleAdsRequest searchGoogleAdsRequest = SearchGoogleAdsRequest.newBuilder().build();
final GoogleAdsServiceClient mockGoogleAdsServiceClient = mock(GoogleAdsServiceClient.class);
final GoogleAdsServiceClient.SearchPagedResponse searchPagedResponse =
mock(GoogleAdsServiceClient.SearchPagedResponse.class);
when(mockGoogleAdsServiceClient.searchPagedCallable()).thenReturn(callable);
when(mockGoogleAdsServiceClient.searchPagedCallable().call(searchGoogleAdsRequest)).thenReturn(searchPagedResponse);
when(searchPagedResponse.iterateAll()).thenReturn(Arrays.asList(mockGoogleAdsRow));
when(mockGoogleAdsServiceClient.search(any())).thenReturn(searchPagedResponse);
当我尝试从某个 Google 库中模拟某些最终的 class 时,例如 SearchGoogleAdsRequest
他们给我 IllegalAccessError
,我添加了 @PrepareForTest
class.
@RunWith(PowerMockRunner.class)
@PrepareForTest({SearchGoogleAdsRequest.class})
@PowerMockIgnore({"javax.net.ssl.*"})
public class GoogleAdsReportDownloaderTest {
final SearchGoogleAdsRequest searchGoogleAdsRequest = PowerMockito.mock(SearchGoogleAdsRequest.class);
final GoogleAdsServiceClient mockGoogleAdsServiceClient = mock(GoogleAdsServiceClient.class);
final GoogleAdsServiceClient.SearchPagedResponse searchPagedResponse =
mock(GoogleAdsServiceClient.SearchPagedResponse.class);
when(mockGoogleAdsServiceClient.searchPagedCallable()).thenReturn(callable);
when(mockGoogleAdsServiceClient.searchPagedCallable().call(searchGoogleAdsRequest)).thenReturn(searchPagedResponse);
when(searchPagedResponse.iterateAll()).thenReturn(Arrays.asList(mockGoogleAdsRow));
when(mockGoogleAdsServiceClient.search(any())).thenReturn(searchPagedResponse);
错误
java.lang.IllegalAccessError: Class com/google/ads/googleads/v6/services/SearchGoogleAdsRequest$MockitoMock53664588 illegally accessing "package private" member of class com/google/protobuf/GeneratedMessageV3$UnusedPrivateParameter
SearchGoogleAdsRequest
final class 看起来像这样,PowerMockito 无法模拟。
public final class SearchGoogleAdsRequest extends GeneratedMessageV3 implements SearchGoogleAdsRequestOrBuilder {
private static final SearchGoogleAdsRequest DEFAULT_INSTANCE = new SearchGoogleAdsRequest();
private static final Parser<SearchGoogleAdsRequest> PARSER = new AbstractParser<SearchGoogleAdsRequest>() {
public SearchGoogleAdsRequest parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException {
return new SearchGoogleAdsRequest(input, extensionRegistry);
}
};
private SearchGoogleAdsRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
this.memoizedIsInitialized = -1;
}
private SearchGoogleAdsRequest() {
this.memoizedIsInitialized = -1;
this.customerId_ = "";
this.query_ = "";
this.pageToken_ = "";
this.summaryRowSetting_ = 0;
}
我可以通过配置 MockMaker 来绕过这个。但是 MockMaker 不能与 PowerMockito 一起工作并给出错误(无法初始化插件,并且某些加载程序应该与 Mockito 一起使用但正在与 PowerMockito 一起加载)。
我需要使用 Power Mockito,因为我需要模拟本地范围对象,而其他人创建的其他单元测试与 MockMaker 不兼容。
我使用 newBuilder 创建 class 的对象解决了这个问题并绕过了这个问题。它并没有真正模拟 class,但在我的情况下我可以将其用作我需要模拟的 class 的参数。如果我们不需要 PowerMockito,那么我们可以将 Mockito 与 MockMaker 一起使用,但是这些 classes 可以很容易地被模拟。
final SearchGoogleAdsRequest searchGoogleAdsRequest = SearchGoogleAdsRequest.newBuilder().build();
final GoogleAdsServiceClient mockGoogleAdsServiceClient = mock(GoogleAdsServiceClient.class);
final GoogleAdsServiceClient.SearchPagedResponse searchPagedResponse =
mock(GoogleAdsServiceClient.SearchPagedResponse.class);
when(mockGoogleAdsServiceClient.searchPagedCallable()).thenReturn(callable);
when(mockGoogleAdsServiceClient.searchPagedCallable().call(searchGoogleAdsRequest)).thenReturn(searchPagedResponse);
when(searchPagedResponse.iterateAll()).thenReturn(Arrays.asList(mockGoogleAdsRow));
when(mockGoogleAdsServiceClient.search(any())).thenReturn(searchPagedResponse);