当前位置: 首页 > 面试题库 >

模拟基于反射的呼叫

闻人越
2023-03-14
问题内容

我正在尝试模拟一些基于反射的方法。您可以在下面看到详细信息,

被测课程

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();
    }
}

测试

public class TracerLogTest {

@Mock
InvocationContext mockContext;
@Mock
Logger mockLogger;
@InjectMocks
private TracerLog cut = new TracerLog();

@BeforeMethod
public void setup() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void logCallTest() throws Exception {
    when(mockContext.proceed()).thenReturn(true);
    when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass");
    cut.logCall(mockContext);
    verify(mockContext).proceed();
}

}

要么

@Test
public void logCallTest() throws Exception {
    when(mockContext.proceed()).thenReturn(true);
    when(mockContext.getMethod().getName()).thenReturn("someMethod");
    when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass");
    cut.logCall(mockContext);
    verify(mockLogger).write(anyString());
    verify(mockContext).proceed();
}

但是,测试失败,并显示NullPointerException。我知道我在嘲笑概念上做错了什么,但是我不明白这是什么。您能否对此加以说明,并建议我如何测试此方法?

谢谢。


问题答案:

您需要一个Method对象和一个Class对象。根据您的评论,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()将返回此测试类的名称(在示例中),但是尽管您无法选择它们返回的内容,但是它们返回的内容仍是确定性的,因此您应该能够验证任何内容你需要。(当然,如果您需要监视或验证是否已对Method对象本身进行了调用,则仍然会遇到问题。)



 类似资料:
  • 我已将JDK升级到版本17。现在,当我尝试在Quarkus上运行optaplanner来运行参数化单元测试时,我得到以下stacktrace: 在读了一点关于这种问题的内容后,我补充道 在以下部分中到我的Maven POM:Quarkus-maven-plugin config和maven-surefire-config 并且在配置文件本机的maven-故障安全-插件配置中: 它确实按预期工作:测

  • 问题内容: 那是测试的方法 我必须模拟三个CacheContext,Method和CacheEnable。有什么想法可以使测试用例更加简单吗? 问题答案: Mockito 可以处理链接的存根: AFAIK,链中的第一个方法返回一个模拟,该模拟被设置为在第二个链式方法调用中返回您的值。 Mockito的作者注意到,这 仅应用于遗留代码 。否则,更好的方法是将行为推送到CacheContext并提供完

  • 我正在AnyLogic中制作一个基于代理的模型,其中代理的行为在StateChart中描述。我想为这些代理分配一定的资源(主要是房间,以节点的形式),这些代理在空间上被放置在某个建筑的蓝图中。例如,请看图一。 当前,该模型通过使用“main.enter_cedicetr.take(this);”这样的函数调用跳出状态图来模拟有限资源的影响。以便使患者继续执行以下DES-PATH: 我的问题是;是否

  • 问题内容: 我要尝试测试其呼叫顺序的三个功能。 假设在模块module.py中,我有以下内容 我想检查b在a之后和c之前被调用。因此,对a,b和c中的每一个进行模拟都是容易的: 检查每个单独的模拟都被调用也很容易。如何检查呼叫相对于彼此的顺序? 将无法使用,因为每个模拟都单独维护。 我尝试使用副作用来记录每个调用: 但这仅给我提供了与模拟一起调用的args,而没有给实际调用的模拟。我可以添加更多逻

  • 有人能告诉我原因或上面代码的更好替代方案吗?

  • 问题内容: 我想使用Mockito测试下面的(简化)代码。我不知道如何告诉Mockito第一次失败,然后第二次成功。 我可以通过以下方式设置成功测试: 以及失败测试: 但是,如何测试一次失败(或两次)然后成功,就可以了吗? 问题答案: 从文档: 有时,对于同一方法调用,我们需要对不同的返回值/异常进行存根。典型的用例可能是模拟迭代器。Mockito的原始版本没有此功能来促进简单的模拟。例如,可以使