/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.powermock.reflect; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.powermock.reflect.context.ClassFieldsNotInTargetContext; import org.powermock.reflect.context.InstanceFieldsNotInTargetContext; import org.powermock.reflect.context.MyContext; import org.powermock.reflect.context.MyIntContext; import org.powermock.reflect.context.MyStringContext; import org.powermock.reflect.context.OneInstanceAndOneStaticFieldOfSameTypeContext; import org.powermock.reflect.exceptions.FieldNotFoundException; import org.powermock.reflect.exceptions.MethodNotFoundException; import org.powermock.reflect.exceptions.TooManyFieldsFoundException; import org.powermock.reflect.exceptions.TooManyMethodsFoundException; import org.powermock.reflect.internal.WhiteboxImpl; import org.powermock.reflect.matching.FieldMatchingStrategy; import org.powermock.reflect.testclasses.AbstractClass; import org.powermock.reflect.testclasses.AnInterface; import org.powermock.reflect.testclasses.Child; import org.powermock.reflect.testclasses.ClassWithAMethod; import org.powermock.reflect.testclasses.ClassWithChildThatHasInternalState; import org.powermock.reflect.testclasses.ClassWithInterfaceConstructors; import org.powermock.reflect.testclasses.ClassWithInterfaceConstructors.ConstructorInterface; import org.powermock.reflect.testclasses.ClassWithInterfaceConstructors.ConstructorInterfaceImpl; import org.powermock.reflect.testclasses.ClassWithInternalState; import org.powermock.reflect.testclasses.ClassWithList; import org.powermock.reflect.testclasses.ClassWithObjectConstructors; import org.powermock.reflect.testclasses.ClassWithOverloadedConstructors; import org.powermock.reflect.testclasses.ClassWithOverloadedMethods; import org.powermock.reflect.testclasses.ClassWithOverriddenMethod; import org.powermock.reflect.testclasses.ClassWithPrimitiveConstructors; import org.powermock.reflect.testclasses.ClassWithPrivateMethods; import org.powermock.reflect.testclasses.ClassWithSerializableState; import org.powermock.reflect.testclasses.ClassWithSeveralMethodsWithSameName; import org.powermock.reflect.testclasses.ClassWithSeveralMethodsWithSameNameOneWithoutParameters; import org.powermock.reflect.testclasses.ClassWithSimpleInternalState; import org.powermock.reflect.testclasses.ClassWithStaticAndInstanceInternalStateOfSameType; import org.powermock.reflect.testclasses.ClassWithStaticMethod; import org.powermock.reflect.testclasses.ClassWithUniquePrivateMethods; import org.powermock.reflect.testclasses.ClassWithVarArgsConstructor; import org.powermock.reflect.testclasses.ClassWithVarArgsConstructor2; import java.io.InputStream; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Tests the WhiteBox's functionality. */ public class WhiteBoxTest { @Rule public ExpectedException expectedException = ExpectedException.none(); @Test public void testFindMethod_classContainingMethodWithNoParameters() throws Exception { Method expected = ClassWithSeveralMethodsWithSameNameOneWithoutParameters.class.getMethod("getDouble"); Method actual = WhiteboxImpl.findMethodOrThrowException( ClassWithSeveralMethodsWithSameNameOneWithoutParameters.class, "getDouble"); assertEquals(expected, actual); } @Test public void testFindMethod_classContainingOnlyMethodsWithParameters() throws Exception { try { WhiteboxImpl.findMethodOrThrowException(ClassWithSeveralMethodsWithSameName.class, "getDouble"); fail("Should throw runtime exception!"); } catch (RuntimeException e) { assertTrue("Error message did not match", e.getMessage().contains( "Several matching methods found, please specify the argument parameter types")); } } @Test public void testFindMethod_noMethodFound() throws Exception { try { WhiteboxImpl.findMethodOrThrowException(ClassWithSeveralMethodsWithSameName.class, "getDouble2"); fail("Should throw runtime exception!"); } catch (RuntimeException e) { assertEquals("Error message did not match", "No method found with name 'getDouble2' with parameter types: [ <none> ] in class " + ClassWithSeveralMethodsWithSameName.class.getName() + ".", e.getMessage()); } } @Test public void testGetInternalState_object() throws Exception { ClassWithInternalState tested = new ClassWithInternalState(); tested.increaseInteralState(); Object internalState = Whitebox.getInternalState(tested, "internalState"); assertTrue("InternalState should be instanceof Integer", internalState instanceof Integer); assertEquals(1, internalState); } @SuppressWarnings("deprecation") @Test public void testGetInternalState_parmaterizedType() throws Exception { ClassWithInternalState tested = new ClassWithInternalState(); tested.increaseInteralState(); int internalState = Whitebox.getInternalState(tested, "internalState", tested.getClass(), int.class); assertEquals(1, internalState); } @Test public void testSetInternalState() throws Exception { ClassWithInternalState tested = new ClassWithInternalState(); tested.increaseInteralState(); Whitebox.setInternalState(tested, "anotherInternalState", 2); assertEquals(2, tested.getAnotherInternalState()); } @Test public void testSetInternalStateWithMultipleValues() throws Exception { ClassWithInternalState tested = new ClassWithInternalState(); final ClassWithPrivateMethods classWithPrivateMethods = new ClassWithPrivateMethods(); final String stringState = "someStringState"; Whitebox.setInternalState(tested, classWithPrivateMethods, stringState); assertEquals(stringState, Whitebox.getInternalState(tested, String.class)); assertSame(classWithPrivateMethods, Whitebox.getInternalState(tested, ClassWithPrivateMethods.class)); } @Test public void testSetInternalState_superClass() throws Exception { ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); tested.increaseInteralState(); Whitebox.setInternalState(tested, "anotherInternalState", 2, ClassWithInternalState.class); assertEquals(2, tested.getAnotherInternalState()); } @Test public void testGetInternalState_superClass_object() throws Exception { ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Object internalState = Whitebox.getInternalState(tested, "internalState", ClassWithInternalState.class); assertEquals(0, internalState); } @SuppressWarnings("deprecation") @Test public void testGetInternalState_superClass_parameterized() throws Exception { ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); int internalState = Whitebox.getInternalState(tested, "internalState", ClassWithInternalState.class, int.class); assertEquals(0, internalState); } @Test public void testInvokePrivateMethod_primtiveType() throws Exception { assertTrue(Whitebox.<Boolean>invokeMethod(new ClassWithPrivateMethods(), "primitiveMethod", 8.2)); } @Test public void testInvokePrivateMethod_primtiveType_withoutSpecifyingMethodName() throws Exception { assertTrue((Boolean) Whitebox.invokeMethod(new ClassWithUniquePrivateMethods(), 8.2d, 8.4d)); } /** * This test actually invokes the <code>finalize</code> method of * <code>java.lang.Object</code> because we supply no method name and no * arguments. <code>finalize</code> is thus the first method found and it'll * be executed. * * @throws Exception */ @Test @Ignore("Invokes different methods on PC and MAC (hashCode on mac)") public void testInvokePrivateMethod_withoutSpecifyingMethodName_noArguments() throws Exception { assertNull(Whitebox.invokeMethod(new ClassWithUniquePrivateMethods())); } @Test public void testInvokePrivateMethod_withoutSpecifyingMethodName_assertThatNullWorks() throws Exception { assertTrue(Whitebox.invokeMethod(new ClassWithUniquePrivateMethods(), 8.2d, 8.3d, null) instanceof Object); } /** * This test should actually fail since equals takes an Object and we pass * in a primitive wrapped as a Double. Thus PowerMock cannot determine * whether to invoke the single argument method defined in * {@link ClassWithUniquePrivateMethods} or the * {@link Object#equals(Object)} method because we could potentially invoke * equals with a Double. */ @Test(expected = TooManyMethodsFoundException.class) public void testInvokePrivateMethod_withoutSpecifyingMethodName_onlyOneArgument() throws Exception { Whitebox.invokeMethod(new ClassWithUniquePrivateMethods(), 8.2d); } @Test(expected = TooManyMethodsFoundException.class) public void testInvokeStaticPrivateMethod_withoutSpecifyingMethodName_onlyOneArgument() throws Exception { assertTrue((Boolean) Whitebox.invokeMethod(ClassWithUniquePrivateMethods.class, 8.2d)); } @Test public void testInvokePrivateMethod_primtiveType_Wrapped() throws Exception { assertTrue((Boolean) Whitebox.invokeMethod(new ClassWithPrivateMethods(), "primitiveMethod", new Double(8.2))); } @Test public void testInvokePrivateMethod_wrappedType() throws Exception { assertTrue((Boolean) Whitebox.invokeMethod(new ClassWithPrivateMethods(), "wrappedMethod", new Double(8.2))); } @Test public void testInvokePrivateMethod_wrappedType_primitive() throws Exception { assertTrue((Boolean) Whitebox.invokeMethod(new ClassWithPrivateMethods(), "wrappedMethod", 8.2)); } @Test public void testMethodWithPrimitiveIntAndString_primitive() throws Exception { assertEquals("My int value is: " + 8, Whitebox.invokeMethod(new ClassWithPrivateMethods(), "methodWithPrimitiveIntAndString", 8, "My int value is: ")); } @Test public void testMethodWithPrimitiveIntAndString_Wrapped() throws Exception { assertEquals("My int value is: " + 8, Whitebox.invokeMethod(new ClassWithPrivateMethods(), "methodWithPrimitiveIntAndString", Integer.valueOf(8), "My int value is: ")); } @Test public void testMethodWithPrimitiveAndWrappedInt_primtive_wrapped() throws Exception { assertEquals(17, Whitebox.invokeMethod(new ClassWithPrivateMethods(), "methodWithPrimitiveAndWrappedInt", new Class[]{int.class, Integer.class}, 9, Integer.valueOf(8))); } @Test public void testStaticState() { int expected = 123; Whitebox.setInternalState(ClassWithInternalState.class, "staticState", expected); assertEquals(expected, ClassWithInternalState.getStaticState()); assertEquals(expected, Whitebox.getInternalState(ClassWithInternalState.class, "staticState")); } @Test public void testStaticFinalPrimitiveState() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("You are trying to set a private static final primitive. Try using an object like Integer instead of int!"); Whitebox.setInternalState(ClassWithInternalState.class, "staticFinalIntState", 123); } @Test public void testStaticFinalStringState() throws NoSuchFieldException { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("You are trying to set a private static final String. Cannot set such fields!"); Whitebox.setInternalState(ClassWithInternalState.class, "staticFinalStringState", "Brand new string"); } @Test public void testStaticFinalObject() throws NoSuchFieldException { int modifiersBeforeSet = ClassWithInternalState.class.getDeclaredField("staticFinalIntegerState").getModifiers(); Integer newValue = ClassWithInternalState.getStaticFinalIntegerState() + 1; Whitebox.setInternalState(ClassWithInternalState.class, "staticFinalIntegerState", newValue); int modifiersAfterSet = ClassWithInternalState.class.getDeclaredField("staticFinalIntegerState").getModifiers(); assertEquals(newValue, ClassWithInternalState.getStaticFinalIntegerState()); assertEquals(modifiersBeforeSet, modifiersAfterSet); } /** * Verifies that the http://code.google.com/p/powermock/issues/detail?id=6 * is fixed. */ @Test(expected = IllegalArgumentException.class) public void testInvokeMethodWithNullParameter() throws Exception { Whitebox.invokeMethod(null, "method"); } @Test(expected = IllegalArgumentException.class) public void testInvokeConstructorWithNullParameter() throws Exception { Whitebox.invokeConstructor(null, "constructor"); } @Test(expected = IllegalArgumentException.class) public void testGetInternalWithNullParameter() throws Exception { Whitebox.getInternalState(null, "state"); } @Test(expected = IllegalArgumentException.class) public void testSetInternalWithNullParameter() throws Exception { Whitebox.setInternalState(null, "state", new Object()); } @Test public void testInstantiateVarArgsOnlyConstructor() throws Exception { final String argument1 = "argument1"; final String argument2 = "argument2"; ClassWithVarArgsConstructor instance = Whitebox.invokeConstructor(ClassWithVarArgsConstructor.class, argument1, argument2); String[] strings = instance.getStrings(); assertEquals(2, strings.length); assertEquals(argument1, strings[0]); assertEquals(argument2, strings[1]); } @Test public void testInstantiateVarArgsOnlyConstructor_noArguments() throws Exception { ClassWithVarArgsConstructor instance = Whitebox.invokeConstructor(ClassWithVarArgsConstructor.class); String[] strings = instance.getStrings(); assertEquals(0, strings.length); } @Test public void testInvokeVarArgsMethod_multipleValues() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); assertEquals(6, Whitebox.invokeMethod(tested, "varArgsMethod", 1, 2, 3)); } @Test public void testInvokeVarArgsMethod_noArguments() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); assertEquals(0, Whitebox.invokeMethod(tested, "varArgsMethod")); } @Test public void testInvokeVarArgsMethod_oneArgument() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); assertEquals(4, Whitebox.invokeMethod(tested, "varArgsMethod", 2)); } @Test public void testInvokeVarArgsMethod_invokeVarArgsWithOneArgument() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); assertEquals(1, Whitebox.invokeMethod(tested, "varArgsMethod", new Class<?>[]{int[].class}, 1)); } @Test public void testInvokePrivateMethodWithASubTypeOfTheArgumentType() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); ClassWithChildThatHasInternalState argument = new ClassWithChildThatHasInternalState(); assertSame(argument, Whitebox.invokeMethod(tested, "methodWithObjectArgument", argument)); } @Test public void testInvokePrivateMethodWithAClassArgument() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); assertEquals(ClassWithChildThatHasInternalState.class, Whitebox.invokeMethod(tested, "methodWithClassArgument", ClassWithChildThatHasInternalState.class)); } @Test public void testSetInternalStateInChildClassWithoutSpecifyingTheChildClass() throws Exception { final int value = 22; final String fieldName = "internalState"; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState() { }; Whitebox.setInternalState(tested, fieldName, value); assertEquals(value, Whitebox.getInternalState(tested, fieldName)); } @Test public void testSetInternalStateInClassAndMakeSureThatTheChildClassIsNotAffectedEvenThoughItHasAFieldWithTheSameName() throws Exception { final int value = 22; final String fieldName = "anotherInternalState"; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState() { }; Whitebox.setInternalState(tested, fieldName, value); assertEquals(value, Whitebox.getInternalState(tested, fieldName)); assertEquals(-1, Whitebox.getInternalState(tested, fieldName, ClassWithInternalState.class)); } @Test(expected = IllegalArgumentException.class) public void testSetInternalStateWithInvalidArgumentType() throws Exception { final int value = 22; final String fieldName = "internalState"; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState() { }; Whitebox.setInternalState(tested, fieldName, new Object()); assertEquals(value, Whitebox.getInternalState(tested, fieldName)); } @Test(expected = IllegalArgumentException.class) public void testSetInternalStateWithNull() throws Exception { final int value = 22; final String fieldName = "internalState"; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState() { }; Whitebox.setInternalState(tested, fieldName, (Object) null); assertEquals(value, Whitebox.getInternalState(tested, fieldName)); } @Test public void testSetAndGetInternalStateBasedOnFieldType() throws Exception { final int value = 22; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, int.class, value); assertEquals(value, (int) Whitebox.getInternalState(tested, int.class)); assertEquals(value, Whitebox.getInternalState(tested, "anotherInternalState")); assertEquals(value, Whitebox.getInternalState(tested, "anotherInternalState", ClassWithChildThatHasInternalState.class)); } @Test public void testSetAndGetInternalStateAtASpecificPlaceInTheHierarchyBasedOnFieldType() throws Exception { final int value = 22; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, int.class, value, ClassWithInternalState.class); assertEquals(42, (int) Whitebox.getInternalState(tested, int.class)); assertEquals(value, (int) Whitebox.getInternalState(tested, int.class, ClassWithInternalState.class)); assertEquals(value, Whitebox.getInternalState(tested, "staticState", ClassWithInternalState.class)); } @Test public void testSetInternalStateBasedOnObjectType() throws Exception { final String value = "a string"; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, value); assertEquals(value, Whitebox.getInternalState(tested, String.class)); } @SuppressWarnings("deprecation") @Test public void testSetInternalStateBasedOnObjectTypeWhenArgumentIsAPrimitiveType() throws Exception { final int value = 22; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, value); assertEquals((Integer) value, Whitebox.getInternalState(tested, "anotherInternalState", ClassWithChildThatHasInternalState.class, Integer.class)); } @Test public void testSetInternalStateBasedOnObjectTypeWhenArgumentIsAPrimitiveTypeUsingGenerics() throws Exception { final int value = 22; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, value); assertEquals((Integer) value, Whitebox.<Integer>getInternalState(tested, "anotherInternalState", ClassWithChildThatHasInternalState.class)); } @Test public void testSetInternalStateBasedOnObjectTypeAtASpecificPlaceInTheClassHierarchy() throws Exception { final String value = "a string"; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, (Object) value, ClassWithInternalState.class); assertEquals(value, Whitebox.getInternalState(tested, "finalString")); } @Test public void testSetInternalStateBasedOnObjectTypeAtASpecificPlaceInTheClassHierarchyForPrimitiveType() throws Exception { final long value = 31; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, value, ClassWithInternalState.class); assertEquals(value, tested.getInternalLongState()); } @Test public void testSetInternalStateBasedOnObjectTypeAtANonSpecificPlaceInTheClassHierarchyForPrimitiveType() throws Exception { final long value = 31; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, value); assertEquals(value, tested.getInternalLongState()); } @Test public void testSetInternalMultipleOfSameTypeOnSpecificPlaceInHierarchy() throws Exception { final int value = 31; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); try { Whitebox.setInternalState(tested, value, ClassWithInternalState.class); fail("should throw TooManyFieldsFoundException!"); } catch (TooManyFieldsFoundException e) { assertEquals("Two or more fields matching type int.", e.getMessage()); } } @Test public void testSetInternalMultipleOfSameType() throws Exception { final int value = 31; ClassWithInternalState tested = new ClassWithInternalState(); try { Whitebox.setInternalState(tested, value); fail("should throw TooManyFieldsFoundException!"); } catch (TooManyFieldsFoundException e) { assertEquals("Two or more fields matching type int.", e.getMessage()); } } @Test public void testSetInternalStateBasedOnObjectSubClassTypeAtASpecificPlaceInTheClassHierarchy() throws Exception { final ClassWithPrivateMethods value = new ClassWithPrivateMethods() { }; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState(); Whitebox.setInternalState(tested, value, ClassWithInternalState.class); assertSame(value, tested.getClassWithPrivateMethods()); } @Test public void testSetInternalStateBasedOnObjectSubClassType() throws Exception { final ClassWithPrivateMethods value = new ClassWithPrivateMethods() { }; ClassWithChildThatHasInternalState tested = new ClassWithChildThatHasInternalState() { }; Whitebox.setInternalState(tested, value); assertSame(value, tested.getClassWithPrivateMethods()); } @Test public void testGetAllInstanceFields() throws Exception { Set<Field> allFields = Whitebox.getAllInstanceFields(new ClassWithChildThatHasInternalState()); assertEquals(8, allFields.size()); } @Test public void testGetAllStaticFields_assertNoFieldsFromParent() throws Exception { Set<Field> allFields = Whitebox.getAllStaticFields(ClassWithChildThatHasInternalState.class); assertEquals(0, allFields.size()); } @Test public void testGetAllStaticFields() throws Exception { Set<Field> allFields = Whitebox.getAllStaticFields(ClassWithInternalState.class); assertEquals(4, allFields.size()); } @Test public void testMethodWithNoMethodName_noMethodFound() throws Exception { try { Whitebox.getMethod(ClassWithInternalState.class, int.class); fail("Should throw MethodNotFoundException"); } catch (MethodNotFoundException e) { assertEquals( "No method was found with parameter types: [ int ] in class org.powermock.reflect.testclasses.ClassWithInternalState.", e.getMessage()); } } @Test public void testMethodWithNoMethodName_tooManyMethodsFound() throws Exception { try { Whitebox.getMethod(ClassWithSeveralMethodsWithSameName.class); fail("Should throw TooManyMethodsFoundException"); } catch (TooManyMethodsFoundException e) { assertTrue(e .getMessage() .contains( "Several matching methods found, please specify the method name so that PowerMock can determine which method you're referring to")); } } @Test public void testMethodWithNoMethodName_ok() throws Exception { final Method method = Whitebox.getMethod(ClassWithSeveralMethodsWithSameName.class, double.class); assertEquals(method, ClassWithSeveralMethodsWithSameName.class.getDeclaredMethod("getDouble", double.class)); } @Test public void testGetTwoMethodsWhenNoneOfThemAreFound() throws Exception { try { Whitebox.getMethods(ClassWithSeveralMethodsWithSameName.class, "notFound1", "notFound2"); } catch (MethodNotFoundException e) { assertEquals( "No methods matching the name(s) notFound1 or notFound2 were found in the class hierarchy of class org.powermock.reflect.testclasses.ClassWithSeveralMethodsWithSameName.", e.getMessage()); } } @Test public void testGetThreeMethodsWhenNoneOfThemAreFound() throws Exception { try { Whitebox.getMethods(ClassWithSeveralMethodsWithSameName.class, "notFound1", "notFound2", "notFound3"); } catch (MethodNotFoundException e) { assertEquals( "No methods matching the name(s) notFound1, notFound2 or notFound3 were found in the class hierarchy of class org.powermock.reflect.testclasses.ClassWithSeveralMethodsWithSameName.", e.getMessage()); } } /** * Asserts that <a * href="http://code.google.com/p/powermock/issues/detail?id=118">issue * 118</a> is fixed. Thanks to cemcatik for finding this. */ @Test public void testInvokeConstructorWithBothNormalAndVarArgsParameter() throws Exception { ClassWithVarArgsConstructor2 instance = Whitebox.invokeConstructor(ClassWithVarArgsConstructor2.class, "first", "second", "third"); assertArrayEquals(new String[]{"first", "second", "third"}, instance.getStrings()); } /** * Asserts that <a * href="http://code.google.com/p/powermock/issues/detail?id=118">issue * 118</a> is fixed. Thanks to cemcatik for finding this. */ @Test public void testInvokeMethodWithBothNormalAndVarArgsParameter() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); assertEquals(4, Whitebox.invokeMethod(tested, "varArgsMethod2", 1, 2, 3)); } @Test public void testInvokePrivateMethodWithArrayArgument() throws Exception { ClassWithPrivateMethods tested = new ClassWithPrivateMethods(); assertEquals("Hello World", Whitebox.invokeMethod(tested, "evilConcatOfStrings", new Object[]{new String[]{ "Hello ", "World"}})); } @Test public void testSetInternalStateFromContext_allStatesInSameOneContext() throws Exception { ClassWithSimpleInternalState tested = new ClassWithSimpleInternalState(); MyContext context = new MyContext(); Whitebox.setInternalStateFromContext(tested, context); assertEquals(context.getMyStringState(), tested.getSomeStringState()); assertEquals(context.getMyIntState(), tested.getSomeIntState()); } @Test public void testSetInternalStateFromContext_statesInDifferentContext() throws Exception { ClassWithSimpleInternalState tested = new ClassWithSimpleInternalState(); MyIntContext myIntContext = new MyIntContext(); MyStringContext myStringContext = new MyStringContext(); Whitebox.setInternalStateFromContext(tested, myIntContext, myStringContext); assertEquals(myStringContext.getMyStringState(), tested.getSomeStringState()); assertEquals(myIntContext.getSimpleIntState(), tested.getSomeIntState()); } @Test public void testSetInternalStateFromContext_contextIsAClass() throws Exception { ClassWithSimpleInternalState tested = new ClassWithSimpleInternalState(); Whitebox.setInternalStateFromContext(tested, MyContext.class); assertEquals(Whitebox.getInternalState(MyContext.class, long.class), (Long) tested.getSomeStaticLongState()); } @Test public void testSetInternalStateFromContext_contextIsAClassAndAnInstance() throws Exception { ClassWithSimpleInternalState tested = new ClassWithSimpleInternalState(); MyContext myContext = new MyContext(); Whitebox.setInternalStateFromContext(tested, MyContext.class, myContext); assertEquals(myContext.getMyStringState(), tested.getSomeStringState()); assertEquals(myContext.getMyIntState(), tested.getSomeIntState()); assertEquals((Long) myContext.getMyLongState(), (Long) tested.getSomeStaticLongState()); } @Test public void testSetInternalStateFromContext_contextHasOneInstanceAndOneStaticFieldOfSameType_onlyInstanceContext() throws Exception { ClassWithStaticAndInstanceInternalStateOfSameType.reset(); ClassWithStaticAndInstanceInternalStateOfSameType tested = new ClassWithStaticAndInstanceInternalStateOfSameType(); OneInstanceAndOneStaticFieldOfSameTypeContext context = new OneInstanceAndOneStaticFieldOfSameTypeContext(); Whitebox.setInternalStateFromContext(tested, context); assertEquals(context.getMyStringState(), tested.getStringState()); assertEquals("Static String state", tested.getStaticStringState()); } @Test public void testSetInternalStateFromContext_contextHasOneInstanceAndOneStaticFieldOfSameType_onlyStaticContext() throws Exception { ClassWithStaticAndInstanceInternalStateOfSameType.reset(); ClassWithStaticAndInstanceInternalStateOfSameType tested = new ClassWithStaticAndInstanceInternalStateOfSameType(); Whitebox.setInternalStateFromContext(tested, OneInstanceAndOneStaticFieldOfSameTypeContext.class); assertEquals(OneInstanceAndOneStaticFieldOfSameTypeContext.getMyStaticStringState(), tested .getStaticStringState()); assertEquals("String state", tested.getStringState()); } @Test public void setInternalStateFromInstanceContextCopiesMatchingContextFieldsToTargetObjectByDefault() throws Exception { ClassWithSimpleInternalState tested = new ClassWithSimpleInternalState(); InstanceFieldsNotInTargetContext fieldsNotInTargetContext = new InstanceFieldsNotInTargetContext(); assertThat(tested.getSomeStringState()).isNotEqualTo(fieldsNotInTargetContext.getString()); Whitebox.setInternalStateFromContext(tested, fieldsNotInTargetContext); assertEquals(tested.getSomeStringState(), fieldsNotInTargetContext.getString()); } @Test public void setInternalStateFromInstanceContextCopiesMatchingContextFieldsToTargetObjectWhenSpecifyingMatchingStrategy() throws Exception { ClassWithSimpleInternalState tested = new ClassWithSimpleInternalState(); InstanceFieldsNotInTargetContext fieldsNotInTargetContext = new InstanceFieldsNotInTargetContext(); assertThat(tested.getSomeStringState()).isNotEqualTo(fieldsNotInTargetContext.getString()); Whitebox.setInternalStateFromContext(tested, fieldsNotInTargetContext, FieldMatchingStrategy.MATCHING); assertEquals(tested.getSomeStringState(), fieldsNotInTargetContext.getString()); } @Test(expected = FieldNotFoundException.class) public void setInternalStateFromInstanceContextThrowsExceptionWhenContextContainsFieldsNotDefinedInTargetObjectWhenSpecifyingStrictStrategy() throws Exception { ClassWithSimpleInternalState tested = new ClassWithSimpleInternalState(); InstanceFieldsNotInTargetContext fieldsNotInTargetContext = new InstanceFieldsNotInTargetContext(); assertThat(tested.getSomeStringState()).isNotEqualTo(fieldsNotInTargetContext.getString()); Whitebox.setInternalStateFromContext(tested, fieldsNotInTargetContext, FieldMatchingStrategy.STRICT); assertEquals(tested.getSomeStringState(), fieldsNotInTargetContext.getString()); } @Test public void setInternalStateFromClassContextCopiesMatchingContextFieldsToTargetObjectByDefault() throws Exception { long state = ClassWithSimpleInternalState.getLong(); try { assertThat(state).isNotEqualTo(ClassFieldsNotInTargetContext.getLong()); Whitebox.setInternalStateFromContext(ClassWithSimpleInternalState.class, ClassFieldsNotInTargetContext.class); assertEquals(ClassFieldsNotInTargetContext.getLong(), ClassWithSimpleInternalState.getLong()); } finally { // Restore the state ClassWithSimpleInternalState.setLong(state); } } @Test public void setInternalStateFromClassContextCopiesMatchingContextFieldsToTargetObjectWhenSpecifyingMatchingStrategy() throws Exception { long state = ClassWithSimpleInternalState.getLong(); try { assertThat(state).isNotEqualTo(ClassFieldsNotInTargetContext.getLong()); Whitebox.setInternalStateFromContext(ClassWithSimpleInternalState.class, ClassFieldsNotInTargetContext.class, FieldMatchingStrategy.MATCHING); assertEquals(ClassFieldsNotInTargetContext.getLong(), ClassWithSimpleInternalState.getLong()); } finally { // Restore the state ClassWithSimpleInternalState.setLong(state); } } @Test(expected = FieldNotFoundException.class) public void setInternalStateFromClassContextThrowsExceptionWhenContextContainsFieldsNotDefinedInTargetObjectWhenSpecifyingStrictStrategy() throws Exception { long state = ClassWithSimpleInternalState.getLong(); try { assertThat(state).isNotEqualTo(ClassFieldsNotInTargetContext.getLong()); Whitebox.setInternalStateFromContext(ClassWithSimpleInternalState.class, ClassFieldsNotInTargetContext.class, FieldMatchingStrategy.STRICT); } finally { // Restore the state ClassWithSimpleInternalState.setLong(state); } } @Test public void assertThatErrorMessageIsCorrectWhenNoInstanceFieldFound() throws Exception { ClassWithInternalState classWithInternalState = new ClassWithInternalState(); try { Whitebox.setInternalState(classWithInternalState, (byte) 23); fail("Should throw a FieldNotFoundException."); } catch (FieldNotFoundException e) { assertEquals( "No instance field assignable from \"java.lang.Byte\" could be found in the class hierarchy of " + ClassWithInternalState.class.getName() + ".", e.getMessage()); } } @Test public void assertThatErrorMessageIsCorrectWhenNoStaticFieldFound() throws Exception { try { Whitebox.setInternalState(ClassWithInternalState.class, (byte) 23); fail("Should throw a FieldNotFoundException."); } catch (FieldNotFoundException e) { assertEquals("No static field assignable from \"java.lang.Byte\" could be found in the class hierarchy of " + ClassWithInternalState.class.getName() + ".", e.getMessage()); } } @Test public void assertThatWhiteboxWorksWithGenericsWhenSpecifyingFieldName() throws Exception { ClassWithInternalState object = new ClassWithInternalState(); Set<String> state = Whitebox.getInternalState(object, "genericState"); assertSame(object.getGenericState(), state); } @Test public void whiteboxGetMethodWithCorrectMethodNameButWrongParameterTypeReturnsErrorMessageReflectingTheWrongParameter() throws Exception { try { Whitebox.getMethod(ClassWithInternalState.class, "methodWithArgument", String.class, InputStream.class); fail("Should throw MethodNotFoundException"); } catch (MethodNotFoundException e) { assertEquals( "No method found with name 'methodWithArgument' with parameter types: [ java.lang.String, java.io.InputStream ] in class org.powermock.reflect.testclasses.ClassWithInternalState.", e.getMessage()); } } @Test public void whiteboxSetInternalStateWorksOnArraysWhenDefiningMethodName() { ClassWithInternalState tested = new ClassWithInternalState(); final String[] expected = new String[]{"string1", "string2"}; Whitebox.setInternalState(tested, "stringArray", expected); assertArrayEquals(expected, tested.getStringArray()); } @Test public void whiteboxSetInternalStateWorksOnArraysWhenNotDefiningMethodName() { ClassWithInternalState tested = new ClassWithInternalState(); final String[] expected = new String[]{"string1", "string2"}; Whitebox.setInternalState(tested, expected); assertArrayEquals(expected, tested.getStringArray()); } @Test public void getInternalStateThrowsIAEWhenInstanceIsNull() { try { Whitebox.getInternalState(null, String.class); fail("Should throw IllegalArgumentException"); } catch (IllegalArgumentException e) { assertEquals("The object containing the field cannot be null", e.getMessage()); } } @Test public void getInternalStateSupportsObjectArrayWhenSUTContainsSerializable() { ClassWithSerializableState tested = new ClassWithSerializableState(); tested.setSerializable(new Serializable() { private static final long serialVersionUID = -1850246005852779087L; }); tested.setObjectArray(new Object[0]); assertNotNull(Whitebox.getInternalState(tested, Object[].class)); } @Test public void getInternalStateUsesAssignableToWhenLookingForObject() { ClassWithList tested = new ClassWithList(); assertNotNull(Whitebox.getInternalState(tested, Object.class)); } @Test(expected = TooManyFieldsFoundException.class) public void getInternalStateThrowsTooManyFieldsFoundWhenTooManyFieldsMatchTheSuppliedType() { ClassWithInternalState tested = new ClassWithInternalState(); assertNotNull(Whitebox.getInternalState(tested, Object.class)); } @Test public void invokeMethodInvokesOverridenMethods() throws Exception { assertTrue(Whitebox.<Boolean>invokeMethod(new ClassWithOverriddenMethod(), 2.0d)); } @Test(expected = IllegalArgumentException.class) public void newInstanceThrowsIAEWhenClassIsAbstract() throws Exception { Whitebox.newInstance(AbstractClass.class); } @Test public void newInstanceReturnsJavaProxyWhenInterface() throws Exception { AnInterface instance = Whitebox.newInstance(AnInterface.class); assertTrue(Proxy.isProxyClass(instance.getClass())); } @Test public void newInstanceCreatesAnEmptyArrayWhenClassIsArray() throws Exception { byte[] newInstance = Whitebox.newInstance(byte[].class); assertEquals(0, newInstance.length); } @Test(expected = IllegalArgumentException.class) public void invokeMethodSupportsNullParameters() throws Exception { ClassWithAMethod classWithAMethod = new ClassWithAMethod(); Connection connection = null; Whitebox.invokeMethod(classWithAMethod, "connect", connection); } @Test(expected = MethodNotFoundException.class) public void invokeOverriddenMethodWithNullParameterThrowsIAE() throws Exception { ClassWithOverloadedMethods tested = new ClassWithOverloadedMethods(); Child child = null; Whitebox.invokeMethod(tested, "overloaded", 2, child); } @Test public void canPassNullParamToPrivateStaticMethod() throws Exception { assertEquals("hello", Whitebox.invokeMethod(ClassWithStaticMethod.class, "aStaticMethod", (Object[])null)); } @Test public void canPassNullParamToPrivateStaticMethodWhenDefiningParameterTypes() throws Exception { assertEquals("hello", Whitebox.invokeMethod(ClassWithStaticMethod.class, "aStaticMethod", new Class<?>[]{byte[].class}, (Object[])null)); } @Test public void canPassNullPrimitiveArraysToAPrivateStaticMethod() throws Exception { assertEquals("hello", Whitebox.invokeMethod(ClassWithStaticMethod.class, "aStaticMethod", (byte[]) null)); } @Test public void canPassMultipleNullValuesToStaticMethod() throws Exception { assertEquals("null null", Whitebox.invokeMethod(ClassWithStaticMethod.class, "anotherStaticMethod", (Object) null, (byte[]) null)); } @Test public void testObjectConstructors() throws Exception { String name = "objectConstructor"; ClassWithObjectConstructors instance = Whitebox.invokeConstructor(ClassWithObjectConstructors.class, name); assertEquals(instance.getName(), name); } @Test public void testInterfaceConstructors() throws Exception { ConstructorInterface param = new ConstructorInterfaceImpl("constructorInterfaceSomeValue"); ClassWithInterfaceConstructors instance = Whitebox.invokeConstructor(ClassWithInterfaceConstructors.class, param); assertEquals(instance.getValue(), param.getValue()); } @Test public void testPrimitiveConstructorsArgumentBoxed() throws Exception { Long arg = 1L; ClassWithPrimitiveConstructors instance = Whitebox.invokeConstructor(ClassWithPrimitiveConstructors.class, arg); assertEquals(instance.getValue(), arg.longValue()); } @Test public void testOverloadedConstructors() throws Exception { String name = "overloadedConstructor"; ClassWithOverloadedConstructors instance = Whitebox.invokeConstructor(ClassWithOverloadedConstructors.class, true, name); assertEquals(instance.getName(), name); assertTrue(instance.isBool()); assertThat(instance.isBool1()).isFalse(); } @Test @Ignore("Reflection and direct call returns different values.") public void testFinalState() { ClassWithInternalState state = new ClassWithInternalState(); String expected = "changed"; Whitebox.setInternalState(state, "finalString", expected); assertEquals(expected, state.getFinalString()); assertEquals(expected, Whitebox.getInternalState(state, "finalString")); } }