【问题标题】:getAnnotation(Class<T>) always returns null when I'm using EasyMock/PowerMock to mock java.lang.reflect.Method当我使用 EasyMock/PowerMock 模拟 java.lang.reflect.Method 时,getAnnotation(Class<T>) 总是返回 null
【发布时间】:2016-01-29 10:28:37
【问题描述】:

被测方法代码如下:

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>

【问题讨论】:

    标签: junit easymock


    【解决方案1】:

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

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

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

    我认为您的问题出在模拟配置中,当我运行您的代码时(使用运行时可用的注释),我得到以下异常:

    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的定义。

    【讨论】:

    • 当我使用具有@Retention(RetentionPolicy.RUNTIME) 的自定义注释时,我得到了相同的结果
    • 我又试了一次,但仍然失败。我在页面中输入了资源。你能帮我解决这个问题吗?谢谢。
    • 是的,你修改的代码运行良好。但是我需要像我的代码一样在另一个方法中使用模拟的方法类,而不是直接使用方法类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多