【问题标题】:Use Mockito 2.0.7 to mock lambda expressions使用 Mockito 2.0.7 模拟 lambda 表达式
【发布时间】:2015-05-06 15:35:28
【问题描述】:

我想像这样模拟我的存储库中提供的查询:

@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() 指定返回值,然后再为所有方法调用指定返回值。
  • 我有一种不好的感觉,你想测试 mockito 而不是测试你的代码。 getByEmail() 的代码是什么?它应该怎么做?

标签: java unit-testing junit lambda mockito


【解决方案1】:

没有必要模拟如此深入的调用。只需模拟 personRepo.findAll() 并让 Streaming API 正常工作:

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

然后代替

.filter( p -&gt; (p.getEmail().equals(Mockito.any(String.class))) )

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

或者,考虑实现PersonRepo.findByEmail

【讨论】:

    【解决方案2】:

    两件事:

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

    首先,您尝试模拟五个不同的方法调用链。 Mockito 不能很好地处理这个问题。尽管 RETURNS_DEEP_STUBS answer(如果放在 personRepo 上)会保存并在适用的情况下返回存根对象,但每次对 when 的调用本身都会存根恰好一个调用。

    其次,Mockito 匹配器不够灵活,无法深入调用;对when 的调用应该只包含一个没有链接的方法调用,对像any 这样的Mockito 匹配器的调用应该是stand in for exactly one of the arguments in that method。按照你的方式,你正在创建一个谓词 p -&gt; (p.getEmail().equals(null)) 并在堆栈上留下一个匹配器以便以后破坏。

    使用Alex Wittig's answer 来解决这个问题,并注意在以后的问题中正确使用匹配器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 2019-04-17
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多