/* * Copyright (c) 2006 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package mockit; import static org.junit.Assert.*; import org.junit.*; public final class ClassInitializationTest { static final class ClassWhichFailsAtInitialization { static { //noinspection ConstantIfStatement,ConstantConditions if (true) { throw new AssertionError(); } } static int value() { return 0; } } @Test public void usingExpectations(@Mocked(stubOutClassInitialization = true) ClassWhichFailsAtInitialization unused) { new Expectations() {{ ClassWhichFailsAtInitialization.value(); result = 1; }}; assertEquals(1, ClassWhichFailsAtInitialization.value()); } static class ClassWithStaticInitializer { static final String CONSTANT = new String("not a compile-time constant"); static String variable; static { variable = doSomething(); } static String doSomething() { return "real value"; } } @Test public void mockClassWithStaticInitializerNotStubbedOut(@Mocked ClassWithStaticInitializer mocked) { assertNotNull(ClassWithStaticInitializer.CONSTANT); assertNull(ClassWithStaticInitializer.doSomething()); assertEquals("real value", ClassWithStaticInitializer.variable); } static class AnotherClassWithStaticInitializer { static final String CONSTANT = new String("not a compile-time constant"); static { doSomething(); } static void doSomething() { throw new UnsupportedOperationException("must not execute"); } int getValue() { return -1; } } @Test public void mockClassWithStaticInitializerStubbedOut( @Mocked(stubOutClassInitialization = true) AnotherClassWithStaticInitializer mockAnother) { assertNull(AnotherClassWithStaticInitializer.CONSTANT); AnotherClassWithStaticInitializer.doSomething(); assertEquals(0, mockAnother.getValue()); } static class ClassWhichCallsStaticMethodFromInitializer { static { String s = someValue(); s.length(); } static String someValue() { return "some value"; } } @Test public void mockUninitializedClass(@Mocked ClassWhichCallsStaticMethodFromInitializer unused) { assertNull(ClassWhichCallsStaticMethodFromInitializer.someValue()); } static class ClassWhichCallsStaticMethodFromInitializer2 { static { someValue().length(); } static String someValue() { return "some value"; } } @Test public void partiallyMockUninitializedClass() { new Expectations(ClassWhichCallsStaticMethodFromInitializer2.class) {{ ClassWhichCallsStaticMethodFromInitializer2.someValue(); }}; assertNull(ClassWhichCallsStaticMethodFromInitializer2.someValue()); } public interface BaseType { String someValue(); } static final class NestedImplementationClass implements BaseType { static { new NestedImplementationClass().someValue().length(); } @Override public String someValue() { return "some value"; } } @Before public void loadNestedImplementationClass() throws Exception { // Ensure the class gets loaded, but not initialized, before it gets mocked. // The HotSpot VM would (for some reason) already have loaded it, but the J9 VM would not. NestedImplementationClass.class.getName(); } @Test public void mockUninitializedImplementationClass(@Capturing BaseType mockBase) { BaseType obj = new NestedImplementationClass(); assertNull(obj.someValue()); } static class Dependency { static Dependency create() { return null; } } static class Dependent { static final Dependency DEPENDENCY = Dependency.create(); static { DEPENDENCY.toString(); } } static class AnotherDependent { static final Dependency DEPENDENCY = Dependency.create(); static { DEPENDENCY.toString(); } } @Mocked Dependency dependency; @Mocked Dependent dependent; @Test public void mockAnotherDependentClass(@Mocked AnotherDependent anotherDependent) { assertNotNull(Dependent.DEPENDENCY); assertNotNull(AnotherDependent.DEPENDENCY); } static class Dependency2 { static Dependency2 create() { return new Dependency2(); } } static class Dependent2 { static final Dependency2 DEPENDENCY = Dependency2.create(); static { DEPENDENCY.toString(); } } @Test public void partiallyMockBothDependencyAndDependentClasses() { new Expectations(Dependency2.class, Dependent2.class) {}; assertNotNull(Dependent2.DEPENDENCY); } static class Dependency3 { static Dependency3 create() { return null; } } static class Dependent3 { static final Dependency3 DEPENDENCY = Dependency3.create(); static { DEPENDENCY.toString(); } } @Test public void partiallyMockDependencyClassThenDependentClass() { final Dependency3 dep = new Dependency3(); new Expectations(Dependency3.class) {{ Dependency3.create(); result = dep; }}; new Expectations(Dependent3.class) {}; assertSame(dep, Dependency3.create()); assertNotNull(Dependent3.DEPENDENCY); } public interface BaseInterface { String DO_NOT_REMOVE = new String("Testing"); } public interface SubInterface extends BaseInterface {} @Mocked SubInterface mock; @Test public void verifyClassInitializerForMockedBaseInterface() { assertNotNull(mock); assertEquals("Testing", BaseInterface.DO_NOT_REMOVE); } static final class ClassWhichCallsMethodOnItselfFromInitializer { static final Integer value = value(); static Integer value() { return null; } } @Test public void mockClassWhichCallsMethodOnItselfFromInitializerWithoutStubbingOutTheInitializer( @Mocked ClassWhichCallsMethodOnItselfFromInitializer unused) { assertNotNull(ClassWhichCallsMethodOnItselfFromInitializer.value()); assertNull(ClassWhichCallsMethodOnItselfFromInitializer.value); } }