如何避免Java中严格的存根参数不匹配

huangapple go评论73阅读模式
英文:

How to avoid strict stubbing argument mismatch in java

问题

I have an object like

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

I use this object in a method like

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

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

But when I test this method I get a strict stubbing argument mismatch

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);
// ...
}

Can someone tell me how to avoid this problem- and create a correct argument?
Thanks for any help!

英文:

I have an object like

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

}

I use this object in a method like

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();
}

But when I test this method I get a strict stubbing argument mismatch

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);

.......

Can someone tell me how to avoid this problem- and create a correct argument?
Thanks for any help!

答案1

得分: 0

你有2-3个解决这个问题的选择。最简单的解决方案是简单地覆盖Person类中的equals方法(或者只需添加lombok的@EqualsAndHashCode - 但这将影响您的生产代码(不仅仅是测试本身)。

或者,您可以在这里使用更通用的Mokito匹配器,以下是一些可以工作的示例:

// 仅基于名称/活动字段进行检查
when(validationService.isValid(
      ArgumentMatchers.argThat(p -> p.getName().equals("Name")))
  )
  .thenReturn(true);

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

// 或者简单地
when(validationService.isValid(Mockito.any()))
  .thenReturn(true);

最后,如果validationService不执行任何I/O操作,您可以尝试以不需要模拟它的方式编写代码/测试。换句话说,如果validationService.isValid(p)只是检查某些状态,也许您可以使用实际对象,并从validationService决定返回有效或无效的Person对象。

在我看来,模拟的越少越好...如果可能的话,我个人会尝试最后一种方法。

英文:

You have 2-3 options for solving this issue. The easiest solution would be to simply override the equals method from the Person class (or simply add lombok's @EqualsAndHashcode - but this will affect your production code (not only the test itself).

Alternatively, you can use a more generic Mokito matcher here are some examples that would work:

// 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);

Lastly, if validationService is not doing any I/O, you can try to write the code/test in such a way that mocking it is not necessary. In other words, if validationService.isValid(p) is just checking some state, maybe you can use the actual object and decide from validationService whether to return a valid or invalid Person object.

In my opinion, the fewer mocks the better... I would personally try this last approach if possible.

huangapple
  • 本文由 发表于 2023年5月30日 01:51:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76359400.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定