在Mockito中什么是“空”对象?

时间:2019-11-29 20:41:05

标签: intellij-idea junit mockito

当我在设置方法中使用@Mock注释和initMocks(this)时,模拟对象在调试器(请注意双引号)及其所有成员中均显示为"null"。为null或0。当我使用Mockito.mock()方法时,看到的是"Mock for MyClass, hashCode: 15422....",这正是我所期望的。我不确定注解方法在做什么,但是还有其他问题可以解决。我的问题是,引号"null"是什么?

1 个答案:

答案 0 :(得分:1)

您不应该期望模拟行为像真实对象一样。他们不是。它们通常涉及各种反射操作和使用通常不会碰到的对象和函数的jvm的低级操作,除非您希望Java开始变得怪异。

因此,不要在没有怪异行为的情况下在调试器中对其进行检查。即使在调试器中从它们读取值也可以更改模拟的状态。假设您将模拟配置为如果多次检查某个值失败,然后在调试器中检查该值,那么模拟会发生什么?

不过,为了彻底回答您的问题,我克隆了模仿存储库,并使用以下命令从src / main目录中搜索带引号的空值:

find . -name *.java -exec grep -Hn "\"null\"" {} \;

并发现以下结果(已编辑)

jomi = / java / org / mockito / internal

j/o/m/i/creation/bytebuddy/SubclassByteBuddyMockMaker:121: return type == null ? "null" : "'" + type.getCanonicalName() + "', loaded by classloader : '" + type.getClassLoader() + "'";
j/o/m/i/creation/bytebuddy/SubclassByteBuddyMockMaker:125: return instance == null ? "null" : describeClass(instance.getClass());
j/o/m/i/matchers/text/ValuePrinter:27: return "null";
j/o/m/i/stubbing/answers/Returns:37: throw wrongTypeOfReturnValue(invocationInfo.printMethodReturnType(), "null", invocationInfo.getMethodName());
j/o/m/i/verification/argumentmatching/ArgumentMatchingTool:48: return m.toString().equals(arg == null ? "null" : arg.toString());

因此,在某些地方返回带引号的null而不是null本身。我怀疑开发人员正在尝试避免空传播,并且将其适当地归类为Null Object pattern的实现([Anderson1996] Bruce Anderson,“空对象”,PLoP '96)。

空对象模式用于通过返回一个真实对象来避免传播空值,该实对象将使您避免空指针异常,但在其他情况下其行为就像是空值。这是一个面向对象的概念,在多态性方面确实非常有效,但是字符串也是一个对象(某种),在必要时可以用空对象表示。您可以检查null值而不是null,并且当下游程序员(或您尝试显示该值的IDE)意外解决该值时,则没有任何实际问题。