Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么不';t null模拟对象抛出NullPointerException?_Java_Unit Testing_Mockito - Fatal编程技术网

Java 为什么不';t null模拟对象抛出NullPointerException?

Java 为什么不';t null模拟对象抛出NullPointerException?,java,unit-testing,mockito,Java,Unit Testing,Mockito,我有一段代码如下所示: 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吗 当我

我有一段代码如下所示:

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指针,因为它试图调用null.doSomething()

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

使用:

when(mockA.getB()).thenReturn(mockB);
...
mockB = null;
thenReturn
将mock设置为返回mockB当时持有的值(即,
执行时…thenReturn
),而不管mockB随后发生了什么

字符串的行为方式没有什么不同:

String s1 = "abc";
String s2 = s1;
s1 = "xyz";
这里的结果是s2仍然具有值“abc”,因为这是分配给它的那一刻的值,不管s1随后发生什么

编辑:

考虑这一点的方法是,像
mockB
s1
s2
这样的变量是“引用”(也称为“指针”)变量,即它们的值指向目标对象内存中的地址

当执行
thenReturn(mockB)
s2=s1
时,传递或复制的是
mockB
s1
值,即目标对象或字符串的地址(而不是变量
mockB
s1
本身的地址)。这就是为什么随后对变量
mockB
s1
本身的值所做的更改没有效果

当。。。然后对对象本身执行的操作没有影响-例如:

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

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

when(mockB.getAge()).thenReturn(23);
...
mockB = null
when(mockA.getB())
的定位不影响(也不受)mock对象的
getName
getAge
的设置,因为这些操作不会更改该对象在内存中的地址。

when(mockA.getB()).thenReturn(mockB);
...
mockB = null;
thenReturn
将mock设置为返回mockB当时持有的值(即,
执行时…thenReturn
),而不管mockB随后发生了什么

字符串的行为方式没有什么不同:

String s1 = "abc";
String s2 = s1;
s1 = "xyz";
这里的结果是s2仍然具有值“abc”,因为这是分配给它的那一刻的值,不管s1随后发生什么

编辑:

考虑这一点的方法是,像
mockB
s1
s2
这样的变量是“引用”(也称为“指针”)变量,即它们的值指向目标对象内存中的地址

当执行
thenReturn(mockB)
s2=s1
时,传递或复制的是
mockB
s1
值,即目标对象或字符串的地址(而不是变量
mockB
s1
本身的地址)。这就是为什么随后对变量
mockB
s1
本身的值所做的更改没有效果

当。。。然后对对象本身执行的操作没有影响-例如:

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

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

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

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

在第一个测试用例中,您模拟的是一个虚拟对象,所以mocikto不会向你报告mockB的空值


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

在第一个测试用例中,您模拟的是一个虚拟对象,因此mocikto不会将mockB的值报告为null


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

wow,感谢您提供的字符串示例。这真的让事情有了正确的角度。。。我的印象是,既然
thenReturn
引用的是一个对象,那么我放置
when…then
s的顺序就无关紧要了。。。虽然我仍然认为第一种方法更直观,但它有帮助;我刚刚在答案中添加了(希望)澄清发生了什么,因此有了正确的想法,它会变得更直观。哇,感谢字符串示例。这真的让事情有了正确的角度。。。我的印象是,既然
thenReturn
引用的是一个对象,那么我放置
when…then
s的顺序就无关紧要了。。。虽然我仍然认为第一种方法更直观,但它有帮助;我刚刚补充了答案(希望)来澄清发生了什么,所以有了正确的想法,它会变得更直观。