当我使用EasyMock / PowerMock来模拟java.lang.reflect.Method时,getAnnotation(Class <t>)总是返回null

时间:2016-01-26 10:02:48

标签: junit easymock

测试方法具有以下代码:

SuppressWarnings suppressWarnings = method.getAnnotation(SuppressWarnings.class);

在我的测试方法中。我模拟了java.lang.reflect.Method:

Method method= PowerMock.createMock(Method.class);  
SuppressWarnings sw = EasyMock.createMock(SuppressWarnings.class);  
EasyMock.expect(method.getAnnotation(SuppressWarnings.class)).andReturn(sw);  

在测试方法中,
method.getAnnotation(SuppressWarnings.class);始终返回null。

我不知道为什么。有人可以帮助我吗?

//code:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Anonymous {

}

public class AnnotationClass {
    public Anonymous fun(Method m){
        Anonymous anonymous = m.getAnnotation(Anonymous.class);
        return anonymous;
    }
}

// test class:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Method.class)
public class AnnotationClassTest {
    @Test
    public void test() throws NoSuchMethodException, SecurityException {
        AnnotationClass testClass = new AnnotationClass();
        final Method mockMethod = PowerMock.createMock(Method.class);
        final Anonymous mockAnot = EasyMock.createMock(Anonymous.class);

        EasyMock.expect(mockMethod.getAnnotation(Anonymous.class)).andReturn(mockAnot);
        PowerMock.replay(mockMethod);

        final Anonymous act = testClass.fun(mockMethod);
        Assert.assertEquals(mockAnot, act);

        PowerMock.verify(mockMethod);
    }
}

error:
java.lang.AssertionError: expected:<EasyMock for interface  
com.unittest.easymock.start.Anonymous> but was:<null>

1 个答案:

答案 0 :(得分:0)

SuppressWarnings@Retention(value=SOURCE),这意味着它在运行时不可用:

  

public static final RetentionPolicy SOURCE:编译器将丢弃注释。

但是,如果您尝试使用在运行时可用的其他注释的代码,method.getAnnotation(MyAnnotation.class)仍会返回null。也就是说,因为默认情况下,模拟的Method将返回null进行方法调用。

我认为你的问题在于mock的配置,当我运行你的代码时(使用运行时可用的注释)我得到以下异常:

Exception in thread "main" java.lang.IllegalStateException: no last call on a mock available
at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:466)
at org.easymock.EasyMock.expect(EasyMock.java:444)
at MockStuff.main(MockStuff.java:54)

This page对如何模拟最终类(例如Method)有一些解释。

您的代码为我提供了完全相同的结果。我能够使用以下代码使其工作:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Method.class)
public class AnnotationClassTest {
  @Test
  public void test() throws NoSuchMethodException, SecurityException {
    final Method mockMethod = PowerMock.createMock(Method.class);
    final Anot mockAnot = EasyMock.createMock(Anot.class);

    EasyMock.expect(mockMethod.getAnnotation(Anot.class)).andReturn(mockAnot);
    PowerMock.replay(mockMethod);

    final Anot methodReturn = mockMethod.getAnnotation(Anot.class);
    Assert.assertEquals(mockAnot, methodReturn);
  }
}

@Retention(RetentionPolicy.RUNTIME)
@interface Anot {}

请注意,此代码是自包含的,我定义了Anot接口,因为您没有给出Anonymous的定义。