Skip to content

Commit

Permalink
Annotations are no copied in the mock, fixes mockito#204
Browse files Browse the repository at this point in the history
Fixed by mockito#171, i.e. by replacing CGLIB by ByteBuddy
  • Loading branch information
bric3 committed Jun 5, 2015
1 parent a258ae8 commit 2c59c46
Showing 1 changed file with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions test/org/mockito/AnnotationsAreCopiedFromMockedTypeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package org.mockito;

import org.fest.assertions.Assertions;
import org.junit.Ignore;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import static java.lang.annotation.ElementType.*;
import static org.mockito.Mockito.mock;

public class AnnotationsAreCopiedFromMockedTypeTest {

@Test
public void mock_should_have_annotations_copied_from_mocked_type_at_class_level() {
AnnotationWithDefaultValue onClassDefaultValue = mock(OnClass.class).getClass().getAnnotation(AnnotationWithDefaultValue.class);
AnnotationWithCustomValue onClassCustomValue = mock(OnClass.class).getClass().getAnnotation(AnnotationWithCustomValue.class);

Assertions.assertThat(mock(OnClass.class).getClass()).isNotSameAs(OnClass.class);
Assertions.assertThat(onClassDefaultValue.value()).isEqualTo("yup");
Assertions.assertThat(onClassCustomValue.value()).isEqualTo("yay");
}

@Test
@Ignore("fields are not copied in the byte buddy mock, this is currently expected")
public void mock_should_have_annotations_copied_from_mocked_type_on_fields() {
AnnotationWithDefaultValue onClassDefaultValue = field("field", mock(OnField.class)).getAnnotation(AnnotationWithDefaultValue.class);
AnnotationWithCustomValue onClassCustomValue = field("field", mock(OnField.class)).getAnnotation(AnnotationWithCustomValue.class);

Assertions.assertThat(onClassDefaultValue.value()).isEqualTo("yup");
Assertions.assertThat(onClassCustomValue.value()).isEqualTo("yay");
}

@Test
public void mock_should_have_annotations_copied_from_mocked_type_on_methods() {
AnnotationWithDefaultValue onClassDefaultValue = method("method", mock(OnMethod.class)).getAnnotation(AnnotationWithDefaultValue.class);
AnnotationWithCustomValue onClassCustomValue = method("method", mock(OnMethod.class)).getAnnotation(AnnotationWithCustomValue.class);

Assertions.assertThat(onClassDefaultValue.value()).isEqualTo("yup");
Assertions.assertThat(onClassCustomValue.value()).isEqualTo("yay");
}

@Test
public void mock_should_have_annotations_copied_from_mocked_type_on_method_parameters() {
AnnotationWithDefaultValue onClassDefaultValue = firstParamOf(method("method", mock(OnMethod.class))).getAnnotation(AnnotationWithDefaultValue.class);
AnnotationWithCustomValue onClassCustomValue = firstParamOf(method("method", mock(OnMethod.class))).getAnnotation(AnnotationWithCustomValue.class);

Assertions.assertThat(onClassDefaultValue.value()).isEqualTo("yup");
Assertions.assertThat(onClassCustomValue.value()).isEqualTo("yay");
}

private AnnotatedElement firstParamOf(Method method) {
final Annotation[] firstParamAnnotations = method.getParameterAnnotations()[0];

return new AnnotatedElement() {
@Override
@SuppressWarnings("unchecked")
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
for (Annotation firstParamAnnotation : firstParamAnnotations) {
if (annotationClass.isAssignableFrom(firstParamAnnotation.getClass())) {
return (T) firstParamAnnotation;
}
}
return null;
}

@Override
public Annotation[] getAnnotations() {
return firstParamAnnotations;
}

@Override
public Annotation[] getDeclaredAnnotations() {
return firstParamAnnotations;
}
};
}

private Method method(String methodName, Object mock) {
for (Method method : mock.getClass().getDeclaredMethods()) {
if(methodName.equals(method.getName())) {
return method;
}
}
throw new IllegalArgumentException("method name not found : " + methodName);
}

private Field field(String fieldName, Object mock) {
for (Field field : mock.getClass().getDeclaredFields()) {
if(fieldName.equals(field.getName())) {
return field;
}
}
throw new IllegalArgumentException("method name not found : " + fieldName);
}

@AnnotationWithDefaultValue
@AnnotationWithCustomValue("yay")
public class OnClass { }


public class OnMethod {
@AnnotationWithDefaultValue
@AnnotationWithCustomValue("yay")
public String method(
@AnnotationWithDefaultValue
@AnnotationWithCustomValue("yay")
String ignored
) { return ""; }
}

public class OnField {
@AnnotationWithDefaultValue
@AnnotationWithCustomValue("yay")
public String field;
}

@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, METHOD, PARAMETER, FIELD})
public @interface AnnotationWithDefaultValue {
String value() default "yup";
}

@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, METHOD, PARAMETER, FIELD})
public @interface AnnotationWithCustomValue {
String value() default "";
}
}

0 comments on commit 2c59c46

Please sign in to comment.