mockito 如何避免java中严格的stubbing参数不匹配

q0qdq0h2  于 2023-06-05  发布在  Java
关注(0)|答案(1)|浏览(204)

我有一个对象

@SuperBuilder(setterPrefix = "set", toBuilder = true;
class Person {
  private final String name;
  private final boolean active;

}

我在一个类似于

public SomeType doSomething(Long id) {
   Person person = personService.getPersonById(id);
   Person updatedPerson = updatePerson(person);
   validationService.isValid(updatedPerson);
    ......
}

private Person updatePerson(Person person) {
  person.toBuilder()
        .setActive(true)
        .build();
}

但是当我测试这个方法时,我得到了一个严格的stubbing参数不匹配

void test() {
 Person person = Person.builder()
   .setName("Name")
   .build();
 Person updatedPerson = Person.builder()
   .setName("Name")
   .setActive(true)
   .build();
when(personService.getPersonById(1L)).thenReturn(person);
when(validationService.isValid(updatedPerson)).thenReturn(false);

.......
有人能告诉我如何避免这个问题-并创建一个正确的论点?感谢您的任何帮助!

wpx232ag

wpx232ag1#

你有2-3个选项来解决这个问题。最简单的解决方案是简单地覆盖Person类中的equals方法(或者简单地添加lombok的@EqualsAndHashcode-但这会影响您的生产代码(不仅是测试本身)。
或者,您可以使用更通用的Mokito匹配器,这里有一些可以工作的示例:

// check solely based on name/active fields
when(validationService.isValid(
      ArgumentMatchers.argThat(p -> p.getName().equals("Name")))
  )
  .thenReturn(true);

// or
when(validationService.isValid(Mockito.any(Person.class)))
  .thenReturn(true);

// or simply
when(validationService.isValid(Mockito.any()))
  .thenReturn(true);

最后,如果validationService没有执行任何I/O,您可以尝试以不需要模拟的方式编写代码/测试。换句话说,如果validationService.isValid(p)只是在检查某个状态,也许你可以使用实际的对象,并从validationService中决定是返回一个有效还是无效的Person对象。
在我看来,嘲笑越少越好…如果可能的话,我个人会尝试最后一种方法。

相关问题