Code example for Method

Methods: getModifiers, setAccessible

0
  @Test 
  public void directlyCallingNativeMethodShouldBeNoOp() throws Exception { 
    Class<?> exampleClass = loadClass(AClassWithNativeMethod.class);
    Object exampleInstance = exampleClass.newInstance();
    Method directMethod = findDirectMethod(exampleClass, "nativeMethod", String.class, int.class);
    assertThat(Modifier.isNative(directMethod.getModifiers())).isFalse();
 
    assertThat(directMethod.invoke(exampleInstance, "", 1)).isNull();
  } 
 
  @Test 
  public void directlyCallingNativeMethodReturningPrimitiveShouldBeNoOp() throws Exception { 
    Class<?> exampleClass = loadClass(AClassWithNativeMethodReturningPrimitive.class);
    Object exampleInstance = exampleClass.newInstance();
    Method directMethod = findDirectMethod(exampleClass, "nativeMethod");
    assertThat(Modifier.isNative(directMethod.getModifiers())).isFalse();
 
    assertThat(directMethod.invoke(exampleInstance)).isEqualTo(0);
  } 
 
  @Test 
  public void shouldHandleMethodsReturningBoolean() throws Exception { 
    Class<?> exampleClass = loadClass(AClassWithMethodReturningBoolean.class);
    classHandler.valueToReturn = true;
 
    Method directMethod = exampleClass.getMethod("normalMethodReturningBoolean", boolean.class, boolean[].class);
    directMethod.setAccessible(true);
    Object exampleInstance = exampleClass.newInstance();
    assertEquals(true, directMethod.invoke(exampleInstance, true, new boolean[0]));
    transcript.assertEventsSoFar("methodInvoked: AClassWithMethodReturningBoolean.__constructor__()",
        "methodInvoked: AClassWithMethodReturningBoolean.normalMethodReturningBoolean(boolean true, boolean[] {})"); 
  } 
 
  @Test 
  public void shouldHandleMethodsReturningArray() throws Exception { 
    Class<?> exampleClass = loadClass(AClassWithMethodReturningArray.class);
    classHandler.valueToReturn = new String[]{"miao, mieuw"};
 
    Method directMethod = exampleClass.getMethod("normalMethodReturningArray");
    directMethod.setAccessible(true);
    Object exampleInstance = exampleClass.newInstance();
    transcript.assertEventsSoFar("methodInvoked: AClassWithMethodReturningArray.__constructor__()");
    assertArrayEquals(new String[] {"miao, mieuw"}, (String[]) directMethod.invoke(exampleInstance));
    transcript.assertEventsSoFar("methodInvoked: AClassWithMethodReturningArray.normalMethodReturningArray()");
  } 
 
  @Test 
  public void shouldInvokeShadowForEachConstructorInInheritanceTree() throws Exception { 
    loadClass(AChild.class).newInstance();
    transcript.assertEventsSoFar(
        "methodInvoked: AGrandparent.__constructor__()", 
        "methodInvoked: AParent.__constructor__()", 
        "methodInvoked: AChild.__constructor__()"); 
  } 
 
  @Test 
  public void shouldRetainSuperCallInConstructor() throws Exception { 
    Class<?> aClass = loadClass(AnInstrumentedChild.class);
    Object o = aClass.getDeclaredConstructor(String.class).newInstance("hortense");
    assertEquals("HORTENSE's child", aClass.getSuperclass().getDeclaredField("parentName").get(o));
    assertNull(aClass.getDeclaredField("childName").get(o));
  } 
 
  @Test 
  public void shouldCorrectlySplitStaticPrepFromConstructorChaining() throws Exception { 
    Class<?> aClass = loadClass(AClassWithFunnyConstructors.class);
    Object o = aClass.getDeclaredConstructor(String.class).newInstance("hortense");
    transcript.assertEventsSoFar(
        "methodInvoked: AClassWithFunnyConstructors.__constructor__(" + AnUninstrumentedParent.class.getName() + " UninstrumentedParent{parentName='hortense'}, java.lang.String foo)",
        "methodInvoked: AClassWithFunnyConstructors.__constructor__(java.lang.String hortense)"); 
 
    // should not run constructor bodies... 
    assertEquals(null, getDeclaredFieldValue(aClass, o, "name"));
    assertEquals(null, getDeclaredFieldValue(aClass, o, "uninstrumentedParent"));
  } 
 
  @Test 
  public void shouldGenerateClassSpecificDirectAccessMethodForConstructorWhichDoesNotCallSuper() throws Exception { 
    Class<?> aClass = loadClass(AClassWithFunnyConstructors.class);
    Object instance = aClass.getConstructor(String.class).newInstance("horace");
    transcript.assertEventsSoFar(
        "methodInvoked: AClassWithFunnyConstructors.__constructor__(" + AnUninstrumentedParent.class.getName() + " UninstrumentedParent{parentName='horace'}, java.lang.String foo)",
        "methodInvoked: AClassWithFunnyConstructors.__constructor__(java.lang.String horace)"); 
 
    // each directly-accessible constructor body will need to be called explicitly, with the correct args... 
 
    Class<?> uninstrumentedParentClass = loadClass(AnUninstrumentedParent.class);
    Method directMethod = findDirectMethod(aClass, "__constructor__", uninstrumentedParentClass, String.class);
    Object uninstrumentedParentIn = uninstrumentedParentClass.getDeclaredConstructor(String.class).newInstance("hortense");
    assertEquals(null, directMethod.invoke(instance, uninstrumentedParentIn, "foo"));
    transcript.assertNoEventsSoFar();
 
    assertEquals(null, getDeclaredFieldValue(aClass, instance, "name"));
    Object uninstrumentedParentOut = getDeclaredFieldValue(aClass, instance, "uninstrumentedParent");
    assertEquals("hortense", getDeclaredFieldValue(uninstrumentedParentClass, uninstrumentedParentOut, "parentName"));
 
    Method directMethod2 = findDirectMethod(aClass, "__constructor__", String.class);
    assertEquals(null, directMethod2.invoke(instance, "hortense"));
    transcript.assertNoEventsSoFar();
 
    assertEquals("hortense", getDeclaredFieldValue(aClass, instance, "name"));
  } 
 
  private Method findDirectMethod(Class<?> declaringClass, String methodName, Class<?>... argClasses) throws NoSuchMethodException {
    String directMethodName = RobolectricInternals.directMethodName(declaringClass.getName(), methodName);
    Method directMethod = declaringClass.getDeclaredMethod(directMethodName, argClasses);
    directMethod.setAccessible(true);
    return directMethod;
  } 
 
  @Test 
  public void shouldInstrumentEqualsAndHashCodeAndToStringEvenWhenUndeclared() throws Exception {