gpt4 book ai didi

java - 如何使用 REFLECTION 或任何其他 API 初始化最终类中的私有(private)变量?

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

这可能听起来很尴尬,但我正在尝试在最终类中初始化私有(private)变量。我已经这样做过很多次了,我知道使用 Reflection 效果很好,但我从未真正在最终类中这样做过。由于我无法实例化该类,因此我无法传递任何对象来设置变量,这就是我陷入困境的地方。

最后一个类

public final class LoggingHandler implements ILoggingHandler {

private Log generalLog;

/**
* @param log The general log.
*/
private void setGeneralLog(Log log) {
generalLog = log;
}

/**
* @return The general log.
*/
private Log getGeneralLog() {
return generalLog;
}

JUnit

@Test
public void testSendDocuments() throws Exception {
AppContext.setApplicationContext( applicationContext );
IClientUserDto iClientUserDto = mock( IClientUserDto.class );

DocusignRESTProvider docusignRestProvider = new DocusignRESTProvider();
docusignRestProvider.setLoggingHandler( iloggingHandler );
docusignRestProvider.setDocumentManager( iDocumentManager );
docusignRestProvider.setConfiguration( iProviderConfiguration );
docusignRestProvider.setManager( iManager );

Field field = LoggingHandler.class.getDeclaredField( "generalLog" );
field.setAccessible( true );
field.set( new Object(), log );

when( iTransformer.transformRequest( any( SendDocumentsTransformerArgs.class ) ) ).thenReturn( iTransformerResult );
docusignRestProvider.sendDocuments( iClientUserDto, iDocumentSet );
}

log 是一个模拟对象。

堆栈跟踪:

java.lang.IllegalArgumentException: Can not set org.apache.commons.logging.Log field com.mercuryinsurance.esignature.common.logging.LoggingHandler.generalLog to java.lang.Object
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
at java.lang.reflect.Field.set(Field.java:741)
at test.com.mercuryinsurance.esignature.integration.provider.docusign.rest.TestDocusignRESTProvider.testSendDocuments(TestDocusignRESTProvider.java:167)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
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:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
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:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

有人可以告诉我还有什么其他方法可以测试这种情况以及如何测试吗?

谢谢

最佳答案

您滥用了 final 类的概念。 Final类可以被实例化,但不能被继承。因此,在您的情况下, LoggingHandler 可以而且应该被实例化,除非它的构造函数是私有(private)的。但如果它的构造函数是私有(private)的 - 这样一个类实现接口(interface)的意义何在?

您应该为 Log 字段创建公共(public) setter 和 getter,实例化 LoggingHandler 实例并在测试中传递您的 Log 对象的模拟。您可以稍后对该模拟进行所需的任何验证。

关于java - 如何使用 REFLECTION 或任何其他 API 初始化最终类中的私有(private)变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43377643/

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