java - 意外异常 org.powermock.reflect.exceptions.ConstructorNotFoundException:无法使用参数类型查找构造函数
问题描述
我使用 Android KeyStore 来存储我的应用程序的一些密钥。我创建了一个 KeyProvider 类来获取我的密钥。我有类似的东西:
public class KeyProvider {
public String getKey(String name) {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.Entry entry = keyStore.getEntry(name, null);
if (entry == null) { // if key is not created, generate key, store it and return
String myKey = "some_key"
KeyStore.SecretKeyEntry secretKeyEntry =
new KeyStore.SecretKeyEntry(
new SecretKeySpec(myKey.getBytes(), KeyProperties.KEY_ALGORITHM_AES));
keyStore.setEntry(name, secretKeyEntry, null);
return myKey;
} else { // else, return it directly
KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) entry;
return String.valueOf(secretKeyEntry.getSecretKey().getEncoded());
}
}
}
不,我正在尝试测试 key 不存在的第一个分支。
@RunWith(PowerMockRunner.class)
@PrepareForTest({KeyProvider.class})
public class KeyProviderTest {
private static final String KEY_STORE_NAME = "AndroidKeyStore";
private static final String ENCRYPTOR_NAME = "otp";
@Mock public KeyStore mKeyStore;
@Mock public KeyStore.SecretKeyEntry mSecretKeyEntry;
@Before
public void setUp() {
PowerMockito.mockStatic(KeyStore.class);
}
@Test
public void testNoExistingKeys() throws Exception {
PowerMockito.when(KeyStore.getInstance(KEY_STORE_NAME)).thenReturn(mKeyStore);
when(mKeyStore.getEntry(ENCRYPTOR_NAME, null)).thenReturn(null);
PowerMockito.whenNew(KeyStore.SecretKeyEntry.class)
.withAnyArguments()
.thenReturn(mSecretKeyEntry);
assertThat(KeyProvider.getKeys(ENCRYPTOR_NAME)).isNotNull();
}
}
但是,我的测试总是失败,原因如下:
[2021-09-06 19:12:50.641][error][tid:22][KeyProvider] Unexpected exception
org.powermock.reflect.exceptions.ConstructorNotFoundException: Failed to lookup constructor with parameter types [ javax.crypto.SecretKey ] in class java.security.KeyStore$SecretKeyEntry.
at org.powermock.reflect.internal.WhiteboxImpl.getConstructor(WhiteboxImpl.java:287)
at org.powermock.api.mockito.internal.invocation.MockitoNewInvocationControl.invoke(MockitoNewInvocationControl.java:41)
at org.powermock.core.MockGateway.newInstanceCall(MockGateway.java:83)
at com.encryptor.otp.KeyProvider.getKeys(KeyProvider.java:45)
at com.encryptor.otp.KeyProviderTest.testNoExistingKeys(KeyProviderTest.java:97)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:136)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:117)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at com.testrunner.DelegateRunnerWithTimeout.lambda$runWithBuckManagedTimeout$0(DelegateRunnerWithTimeout.java:116)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NoSuchMethodException: java.security.KeyStore$SecretKeyEntry.<init>(javax.crypto.SecretKey)
at java.base/java.lang.Class.getConstructor0(Class.java:3349)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2553)
at org.powermock.reflect.internal.WhiteboxImpl.getConstructor(WhiteboxImpl.java:279)
... 36 more
我不明白为什么 whenNew 的电源模拟不起作用。任何帮助,将不胜感激!
解决方案
推荐阅读
- genexus - 在 Genexus beforeConnect 程序中隐藏密码
- java - 带有输出参数的存储过程自动化引发错误:将数据类型 nvarchar 转换为 int 时出错
- java - 如何使用 redis 模板手动使用 redis 初始缓存名称
- mysql - ER_NOT_SUPPORTED_AUTH_MODE mysql vscode
- chronicle-map - 为什么从当前存储库下载后编年史地图无法正确构建
- excel - 我需要帮助在 VBA 的一列中截断超过 40 个字符
- kubernetes - Kubernetes - 如何在 Kubernetes 上部署 Filebeat?
- android - Kotlin:打开 ImagePicker 时应用程序崩溃
- c++ - C++中的线程队列
- java - 杰克逊冲突的二传手,即使是 @JsonIgnore 和 @JsonProperty