java - 使用 mockito 捕获方法引用

标签 java lambda mockito

我正在尝试模拟一个名为 Worker 的协作者,并捕获其在不同线程中运行的方法 execute 的参数。 但是,该方法本身将方法引用作为参数:childService::listClientschildService::refreshObjects。 当我使用捕获的参数断言方法引用时,我得到了不同的 lambda 对象。

有没有办法以正确的方式接触和断言它们?

正在测试的类:

public class ParentService {
    private ChildService childService;
    private Worker worker;
    ...
    public void doAction() {
        worker.execute(
                childService::listClients,
                childService::refreshObjects
        );
    }
}

测试:

@Test
public void shouldUseChildService() {
    ArgumentCaptor<Callable> callableCaptor = ArgumentCaptor.forClass(Callable.class);
    ArgumentCaptor<Consumer> consumerCaptor = ArgumentCaptor.forClass(Consumer.class);

    parentService.doAction();

    verify(worker).execute(callableCaptor.capture(), consumerCaptor.capture());
    assertEquals((Callable) childService::listClients, callableCaptor.getValue());
    assertEquals((Consumer) childService::refreshObjects, consumerCaptor.getValue());
}

断言错误:

    java.lang.AssertionError: 
    Expected :org.app.services.ParentServiceTest$$Lambda$4/990416209@1786dec2
    Actual   :org.app.services.ParentServiceTest$$Lambda$1/1340328248@74650e52
at org.junit.Assert.failNotEquals(Assert.java:743)
    at org.junit.Assert.assertEquals(Assert.java:118)
    at org.junit.Assert.assertEquals(Assert.java:144)
    at org.app.services.ParentServiceTest.shouldUseChildService(ParenServiceTest.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

最佳答案

首先使用 Mockito 模拟您的 Worker(就像您所做的那样)。同时模拟您的 ChildService。然后:

@Test
public void shouldUseChildService() {
  ArgumentCaptor<Callable> callableCaptor = ArgumentCaptor.forClass(Callable.class);
  ArgumentCaptor<Consumer> consumerCaptor = ArgumentCaptor.forClass(Consumer.class);

  parentService.doAction();

  verify(worker).execute(callableCaptor.capture(), consumerCaptor.capture());
  callableCaptor.getValue().call(); //this will execute whatever was captured
  consumerCaptor.getValue().accept(null);//this will execute whatever was captured

  // now verify that childService::listClients and childService::refreshObjects have been called
}

关于java - 使用 mockito 捕获方法引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34807210/

相关文章:

java - 快速找到windows文件夹中的java类

java - 错误 : method displayOldestAge(List<Player>)

java - 如何直接提供对可选列表的方法引用?

c# - 动态获取 Func<T,bool> 调用的结果

android - Mockito 空指针异常

java - Seam Solder 的 @Requires 注释应该接收字符串还是类?

java - 将文件上传到 android 的 firebase 存储中的用户特定目录?

java - 增强的 'for' 循环和 lambda 表达式

flutter - 如何验证方法内部的方法在 mockito 中被调用

java - 同一类中的模拟方法