Java 模拟基于反射的调用

Java 模拟基于反射的调用,java,mocking,ejb-3.0,mockito,Java,Mocking,Ejb 3.0,Mockito,我试图模仿一些基于反射的方法。下面您可以看到详细信息 正在测试的类 public class TracerLog { @AroundInvoke public Object logCall(InvocationContext context) throws Exception { Logger logger = new Logger(); String message = "INFO: Invoking method - "

我试图模仿一些基于反射的方法。下面您可以看到详细信息

正在测试的类

public class TracerLog {
    @AroundInvoke
    public Object logCall(InvocationContext context) throws Exception {
        Logger logger = new Logger();
        String message = "INFO: Invoking method - " 
                + context.getMethod().getName() + "() of Class - " 
                + context.getMethod().getDeclaringClass();

        logger.write(message);
        return context.proceed();
    }
}
试验

}

但是,测试失败,出现NullPointerException。我知道我在反对嘲弄概念时犯了错误,但我不明白这是什么。你能给我介绍一下这个方法,并告诉我如何测试这个方法吗


谢谢。

您需要一个方法对象和一个类对象。根据您的评论,Mockito无法模拟方法,因此您需要一个真正的方法。我还没有测试过这个,但我相信它会起作用。而不是:

when(mockContext.getMethod().getName()).thenReturn("someMethod");
when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass");
你需要:

// any method will do, but here is an example of how to get one.
Method testMethod = this.getClass().getMethod("logCallTest");

when(mockContext.getMethod()).thenReturn(testMethod);

显然,
getName()
将不再返回“someMethod”,而
getDeclaringClass().getName()
将返回此测试类的名称(在示例中),但尽管您无法选择它们返回的内容,但它们返回的内容仍然是确定的,因此您应该能够验证您需要的任何内容。(当然,如果您需要监视或验证是否对方法对象本身进行了调用,您仍然会被卡住。)

是的,问题是
mockContext.getMethod()
将返回null。因此,每次运行它时,然后对结果调用一些东西(getDeclaringClass()或getName()),您将得到NPE。在设置模拟时,您可能希望使用
返回\u DEEP\u STUBS
默认答案。差不多

@Mock( answer = RETURNS_DEEP_STUBS ) private InvocationContext mockContext; 

应该这样做。

您如何创建模拟对象和测试对象?您可以发布整个测试类,而不仅仅是测试方法吗?谢谢。@DavidWallace我现在已经编辑了这个问题以包含完整的代码。谢谢你的回答,但是Mockito抱怨说它不能模拟或监视java.lang.reflect.Method。有没有其他方法可以实现这一点?我已经编辑了我的答案,以展示如何使用真实的方法对象。这应该可以解决您问题中的简单示例,但仍然存在局限性。感谢您的建议,但是mockContext.getMethod().getDeclaringClass()在这种情况下不起作用。为什么不呢?实方法确实有一个声明类。所以你会得到真正的声明类。嗨,大卫,我基本上同意你。但对于读者来说:该方法是最后一个类,不能用Mockito来模拟;)我也不建议你模仿你不拥有的类型。哦,麻烦了。布里斯是对的(在这些事情上,他通常是对的)。因为Mockito不能模拟最后的课程,所以我看不出有什么方法可以达到原始海报的要求。抱歉。@Brice好吧,我同意你的看法,但是InvocationContext不是最终的类,在我的例子中它必须被模拟,因为我不希望应用程序服务器为我的测试运行。我哪里做错了吗?@Bala我只是在说方法课,你应该用杰里克斯的答案,大卫,我也会错过一件事;)@另一方面,Brice of当然不能使用Mockito模拟java.lang.reflect.Method。这就是我需要帮助的地方。你能告诉我怎么处理这件事吗?
// any method will do, but here is an example of how to get one.
Method testMethod = this.getClass().getMethod("logCallTest");

when(mockContext.getMethod()).thenReturn(testMethod);
@Mock( answer = RETURNS_DEEP_STUBS ) private InvocationContext mockContext;