Java 用mockito捕获方法引用

Java 用mockito捕获方法引用,java,lambda,mockito,Java,Lambda,Mockito,我试图模拟一个名为Worker的协作者,并捕获其方法execute的参数,该方法在不同的线程中运行。 但是,方法本身有方法引用作为参数:childService::listClients和childService::refreshObjects。 当我用捕获的参数断言方法引用时,会得到不同的lambda对象 有没有一种方法能够以适当的方式达到和维护这些目标 正在测试的类: public class ParentService { private ChildService childSer

我试图模拟一个名为
Worker
的协作者,并捕获其方法
execute
的参数,该方法在不同的线程中运行。 但是,方法本身有方法引用作为参数:
childService::listClients
childService::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());
}

首先用Mockito模拟您的
工作人员
(就像您所做的那样)。还要模拟您的
儿童服务
。然后:

@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
}
@测试
public void应该使用childservice(){
ArgumentCaptor callableCaptor=ArgumentCaptor.forClass(Callable.class);
ArgumentCaptor consumerCaptor=ArgumentCaptor.forClass(Consumer.class);
parentService.doAction();
验证(worker.execute)(callableCaptor.capture(),consumerCaptor.capture());
callableCaptor.getValue().call();//这将执行捕获的任何内容
consumercator.getValue().accept(null);//这将执行捕获的任何内容
//现在验证是否调用了childService::ListClient和childService::refreshObjects
}

这不是lambda表达式的问题,而是概念问题。给定两个
可调用的
,它们何时相等?消费者的情况也一样,他们什么时候相等?@Tunaki我编辑了第二个断言。你是说这些对象不能与assertTrue进行比较吗?我还对childService.listClients()方法进行了存根,但结果是一样的。问题是,您想断言什么?似乎您要做的是验证是否调用了
listClients
refreshObjects
,对吗?不,这是典型的XY问题。要验证是否调用了它们,可以模拟
childService
并使用
Mockito.verify
验证其行为。可以模拟childService,模拟worker,使mock worker.execute()方法使用自定义Mockito应答调用其两个参数,调用父服务,并验证ListClient()和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());
  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
}