使用Mockito 2.0.7模拟lambda表达式

我想模拟我的存储库上提供的查询,如下所示:

@Test public void GetByEmailSuccessful() { // setup mocks Mockito.when(this.personRepo.findAll() .stream() .filter(p -> (p.getEmail().equals(Mockito.any(String.class)))) .findFirst() .get()) .thenReturn(this.personOut); Mockito.when(this.communityUserRepo.findOne(this.communityUserId)) .thenReturn(this.communityUserOut); ... 

我的@Before方法如下所示:

 @Before public void initializeMocks() throws Exception { // prepare test data. this.PrepareTestData(); // init mocked repos. this.personRepo = Mockito.mock(IPersonRepository.class); this.communityUserRepo = Mockito.mock(ICommunityUserRepository.class); this.userProfileRepo = Mockito.mock(IUserProfileRepository.class); } 

可悲的是,当我运行测试时,我收到错误:

java.util.NoSuchElementException:没有值存在

当我双击错误时,它指向第一个lambda的.get()方法。

有没有人成功嘲笑过一个lambda表达式,知道如何解决我的问题?

没有必要嘲笑这么深的电话。 只需模拟personRepo.findAll()并让Streaming API正常工作:

 Person person1 = ... Person person2 = ... Person person3 = ... List people = Arrays.asList(person1, person2, ...); when(personRepo.findAll()).thenReturn(people); 

而不是

.filter(p -> (p.getEmail().equals(Mockito.any(String.class))))

只需在Person对象上设置/模拟email即可获得预期值。

或者,考虑实现PersonRepo.findByEmail

两件事情:

 Mockito.when(this.personRepo.findAll() .stream() .filter(p -> (p.getEmail().equals(Mockito.any(String.class)))) .findFirst() .get()) .thenReturn(this.personOut); 

首先,您正在尝试模拟五个不同方法调用的链。 Mockito不能很好地处理这个问题; 虽然RETURNS_DEEP_STUBS应答 (如果放在personRepo上)会保存并返回存根对象(如果适用),每次调用when本身都会截断一个调用。

其次,Mockito匹配器不够灵活,无法在通话中深入工作; 调用when应该只包含一个没有链接的方法调用,并且调用Mockito匹配器就像any应该代表该方法中的一个参数 。 你拥有它的方式,你正在创建一个谓词p -> (p.getEmail().equals(null))并在堆栈上留下一个匹配器以便以后解决问题。

使用FiveNine的答案来解决这个问题,并注意在未来的问题中正确地使用匹配器和使用匹配器。