【问题标题】:Why Mockito's mock returns 0 when it should return null?为什么 Mockito 的 mock 在应该返回 null 时返回 0?
【发布时间】:2014-10-28 05:40:16
【问题描述】:

当某个对象具有装箱类型属性时,该属性的 getter 返回0。但这应该返回null,因为boxed type 属性的默认值是null。这里有什么问题?

class Person {
    private Long id;

    public Long getId() {
        return id;
    }
}
...

@Mock Person person;

...
person.getId(); // 0 instead of null

【问题讨论】:

  • 此代码无法编译:缺少 getId() 方法的返回类型。而且它相当重要,因为如果它是 Long,那么默认值(对于未初始化的对象)是 null。如果它很长,则未初始化的 long(原语)的值为 0,尽管在这种情况下,我会在尝试取消装箱 null Double 时出现 NullPointerException。但是请更正代码?
  • @Paul 哦,感谢您发现这一点。固定。

标签: java unit-testing mocking mockito


【解决方案1】:

这只是在默认 Mockito 答案中为原始类型和包装类型选择的默认值。

【讨论】:

  • 返回值不能多样化吗?
  • 当然可以在存根时自定义默认值。但是我假设您的意思是更改默认答案的默认值,在这种情况下,它当前尚未实现,但是可以更改模拟的默认答案。
  • 我希望null 用于Long0 用于long
  • @aliopi 前段时间已经讨论过这种观点,原始包装器用于原始包装,不应返回为 null。这可能让人觉得很自以为是,但我们强烈支持良好的编程实践,因此我们尽可能避免返回 null。
  • 是的,在您的沙箱/上下文中是的。但是在工作中,返回0 而不是nullcountX 方法让我相信服务找到了0 对象,而实际上它是自以为是的模拟。
【解决方案2】:

我遇到了同样的问题,我的解决方案是将模拟的默认答案更改为null

Person person;

...
person = mock(Person.class, new Answer<Object>() {
  @Override
  public Object answer(InvocationOnMock invocation) throws Throwable {
    return null;
  }
});
person.getId(); // null!

(如果要使用@Mock注解,不确定是否可以设置默认答案)

如果出于某种原因您只想为Long 设置默认值(而不是例如Integer),这应该可以在answer 方法中解决问题:

if(invocation.getMethod().getReturnType().equals(Long.class)){
  return null;
}else{
  return Mockito.RETURNS_DEFAULTS.answer(invocation);
}

【讨论】:

  • 或者,您可以像往常一样创建一个Person 模拟(例如mock(Person.class))并将其getId() 方法存根以返回null,如下所示:when(person.getId()).thenReturn(null)
【解决方案3】:

这是 getter 方法返回的正确值。

当您在 Mokito 中模拟一个类时,该类中的所有方法也会被模拟。所以本质上这与将装箱类型属性设置为 Null 无关。如您所见,它的 LONG 值作为实例变量,默认值为 0L。

因此 person.getId() 将始终返回 0 而不是 NULL。

【讨论】:

  • 你能详细解释一下吗
猜你喜欢
  • 1970-01-01
  • 2020-02-27
  • 2021-07-12
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
相关资源
最近更新 更多