gpt4 book ai didi

java - 为什么 null Mock 对象不会抛出 NullPointerException?

转载 作者:行者123 更新时间:2023-12-02 01:07:14 25 4
gpt4 key购买 nike

我有一段代码,如下所示:

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()。

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

最佳答案

与:

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

thenReturn设置mock以返回mockB在那一刻(即执行when ... thenReturn的那一刻)所持有的值,无论mockB随后发生什么。

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

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

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

编辑:

考虑这个问题的方法是像 mockB 这样的变量, s1s2是“引用”(又名“指针”)变量 - 也就是说,它们的值指向目标对象内存中的地址。

何时 thenReturn(mockB)s2 = s1被执行,它是mockBs1正在传递或复制 - 即目标对象或字符串的地址(不是变量 mockBs1 本身的地址)。这就是变量mockB的值随后发生变化的原因。或s1本身没有任何影响。

when ... then的定位在哪里对对象本身执行的操作没有影响 - 例如:

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

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

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

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

关于java - 为什么 null Mock 对象不会抛出 NullPointerException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59853559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com