Problem:
In order to test a given class I need to be able to mock ClassWithBadStaticFinalField
I am unable to modify ClassWithBadStaticFinalField
Mocking ClassWithBadStaticFinalField
with mockito is not possible because it attempts to interact with production servers when initialising its bad static final field
I have attempted to hack the field in the manner described in this answer but that fails with the following stacktrace
java.lang.ExceptionInInitializerError
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:140)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1057)
at java.lang.reflect.Field.getFieldAccessor(Field.java:1038)
at java.lang.reflect.Field.set(Field.java:741)
at com.example.SomeTest.setFinalStatic(SomeTest.java:76)
at com.example.SomeTest.setUp(SomeTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.NullPointerException
at com.example.ClassWithBadStaticFinalField.<clinit>(ClassWithBadStaticFinalField.java:17)
... 34 more
ClassWithBadStaticFinalField.java
public abstract class ClassWithBadStaticFinalField {
protected static final String SOME_STRING = SomeRidiculousClass.someInsaneStaticMethodWhichDoesBadThings();
public ClassWithBadStaticFinalField() { // line 17
}
...
}
I have requested that ClassWithBadStaticFinalField
have an interface created which details all public methods, and so gets me out of this problem, but wheels turn slowly..
When the production servers are not available SomeRidiculousClass.someInsaneStaticMethodWhichDoesBadThings()
null pointers
I would rather not have to intercept the outbound call made from SomeRidiculousClass.someInsaneStaticMethodWhichDoesBadThings()
and force a response back.