当前位置: 首页 > 知识库问答 >
问题:

为什么null模拟对象不抛出NullPointerException?

钱和平
2023-03-14

我有一段类似这样的代码:

public void someMethod(ObjectA a) {
    ObjectB b = a.getB();
    b.doSomething();
}

我的测试是:

@Test
public void someTest_1() {
    when(mockA.getB()).thenReturn(mockB);
    ...
    mockB = null;

    someMethod(mockA);
}

上面的代码不应该抛出NPE吗?

当我将测试更改为:

@Test
public void someTest_2() {
    when(mockA.getB()).thenReturn(null);

    someMethod(mockA);
}

然后我的代码正确地抛出了一个空指针异常。

我的测试第一版和第二版有什么区别?

在我的第一个版本中,我告诉mockA返回mockB。但是我也将mockB设置为null,所以当调用b.doSomething()时,我认为该方法应该抛出一个空指针,因为它试图调用null.doSomething()。

我知道我应该使用第二个版本来测试我试图测试的行为,但我不知道为什么第一个版本有不同的行为。

共有2个答案

林礼骞
2023-03-14

在第一个测试用例中,您正在模拟一个虚拟对象,所以mocikto不会向您报告mockB为null。

在第二个测试用例中,您显式地将代码返回null。

欧阳俊捷
2023-03-14

使用:

when(mockA.getB()).thenReturn(mockB);
...
mockB = null;

thenReturn 将 mock 设置为返回 mockB 在那一刻持有的值(即,当 ...然后返回被执行),无论随后的 mockB 发生了什么。

这与字符串的行为没有太大的不同:

String s1 = "abc";
String s2 = s1;
s1 = "xyz";

这里的结果是,s2仍然具有值“abc”,因为这是分配给它的那一刻的值,无论s1随后发生什么。

编辑:

考虑这一点的方法是,像< code>mockB、< code>s1和< code>s2这样的变量是“引用”(又名“指针”)变量——也就是说,它们的值指向目标对象在内存中的地址。

当执行thenReturn(mockB)s2=s1,传递或复制的是mockB和s1的值-即目标对象或字符串的地址(而不是变量mockB,或s1 本身的地址)。这就是为什么随后对变量mockBs1,本身的值进行更改不会产生任何影响。

<代码>的定位在哪里当...则对象本身执行的操作没有影响,例如:

when(mockB.getName()).thenReturn("fred");

when(mockA.getB()).thenReturn(mockB);

when(mockB.getAge()).thenReturn(23);
...
mockB = null

当(mockA.getB())的定位不影响(也不受)模拟对象的getNamegetage的设置,因为这些操作不会更改该对象在内存中的地址。

 类似资料:
  • 问题内容: 根据文档,该方法返回: 如果参数是,则字符串等于; 否则,返回的值。 但是,当我尝试这样做时,怎么会这样: 它会抛出NPE吗?(如果你不相信,请自己尝试!) 怎么会这样呢?文件在骗我吗?这是Java中的主要错误吗? 问题答案: 问题是方法已重载: String.valueOf(Object) String.valueOf(char[]) Java规范语言要求在这种情况下,选择最具体的重

  • 问题内容: 考虑以下之一: 在这里,Sysout必须使用String。因此,必须在实例上调用toString()。 那么为什么null.toString()很棒呢?Sysout会照顾这个吗? 编辑:其实我用StringBuilder的append()看到了这怪异的东西。因此尝试了Sysout。两者的行为方式相同。那该方法也要注意吗? 问题答案: 的调用(即编写时调用的方法),如Javadoc中所述

  • 下面是我的代码。当我运行它时,我在线程“main”java.lang.IndexOutOfBoundsException:Index:3、Size:2中得到异常,而不是我的异常消息。谁能解释一下我做错了什么,为什么会这样?谢谢!

  • 我知道在原始数据类型的情况下自动类型提升的概念。但在参考数据类型的情况下,我有下面的代码可以完美地工作。 这给出了输出Array。 但是如果代替Object o,如果我们有任何其他类,那么这将显示编译时错误该方法对于Test4类型是模糊的 下面的代码给出编译时错误 正如我所知,每个引用数据类型(类、接口和数组)的默认值都是null。 那么为什么上面的代码在对象o的情况下工作呢。 提前谢谢

  • 问题内容: 运行此命令时: 响应为: 这对我来说真是太棒了。我本以为这会带来编译时错误。 为什么我可以在Java中抛出null,为什么将其转换为NullPointerException? (实际上,鉴于我抛出的是null,因此我不知道这是否是“ upcast”) 除了一个非常愚蠢的面试问题(请没人在面试中问这个问题)之外,我看不到任何理由。也许您想被解雇,但这就是…我的意思是,为什么还会有人呢?

  • 我正在为一个处理订单和设置完成的订单准备发货的类编写一些测试。为客户检索订单,并使用已完成订单的订单状态来完成处理。然而,当我运行测试时,它们失败了,说“不能在空对象上获得completedLines...”从错误中可以清楚地看出OrderStatus对象为NULL。但是,我在创建测试时设置了它,如下所示