This may sound awkward but I am trying to initialize a private variable in a final class. I've done this many times and I know it works very well using Reflection
but I have never really done this with a final class. Since I cannot instantiate the class i cannot pass any object to set the variable and this is where I am stuck.
Final class
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
is a mocked object.
stack trace:
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)
Can someone let me know what other approach is there to test such a condition and how?
Thanks
You are misusing the concept of a final
class. Final classes CAN be instantiated, they cannot be inherited. So, in your case LoggingHandler
can and should be instantiated unless its constructor is private. But if its constructor is private - what is the point of such a class implementing an interface?
You should create public setters and getters for Log
field, instantiate a LoggingHandler
instance and pass there a mock of you Log
object within test. You can do whatever verifications you need on that mock later.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.