使用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的答案来解决这个问题,并注意在未来的问题中正确地使用匹配器和使用匹配器。