And*_*ndy 5 java junit mockito
所以我有这段代码引发 NullPointerException
NumberFormat formatterFake = mock(NumberFormat.class);
when(formatterFake.format(1)).thenReturn("1");
Run Code Online (Sandbox Code Playgroud)
问题是我在 when() 方法中遇到异常:
java.lang.NullPointerException
at java.text.NumberFormat.format(NumberFormat.java:297)
Run Code Online (Sandbox Code Playgroud)
我还尝试模拟具体类,得到相同的结果。
java.lang.NullPointerException
at java.text.NumberFormat.format(NumberFormat.java:297)
Run Code Online (Sandbox Code Playgroud)
我对 Mockito 有点陌生,任何帮助都会非常困难。提前致谢。
好的,所以您在这里所做的一切都是为了在模拟上存根方法。
NumberFormat是一个抽象类。这通常很好,因为 Mockito 可以像普通类一样模拟抽象类。问题与该方法的实现有关NumberFormat#format(long)。
看一下我使用Oracle jdk 1.7.0 update 2的实现的源代码,你可以看到这个方法的作用:
public final String format(long number) {
return format(number, new StringBuffer(), DontCareFieldPosition.INSTANCE).toString();
}
Run Code Online (Sandbox Code Playgroud)
您正在嘲笑的格式方法实际上正在调用另一个格式方法:NumberFormat#format(long, StringBuffer, FieldPosition)它驻留在同一个抽象类中。然后它返回调用该调用结果toString()的结果。这是一个FINAL方法,Mockito 无法对其进行存根。
当您使用“when-then”语法来存根方法时,Mockito 实际上会调用您要存根的方法(如果它有最终实现)。所以当你写:
when(formatterFake.format(1))
Run Code Online (Sandbox Code Playgroud)
format您实际上正在调用抽象类中实现的方法的第一个重载NumberFormat。
第一个重载的最终实现format调用第二个format方法。第二个format 是. NumberFormat所以没有可调用的实现。
没问题,我们正在使用模拟。Mockito 为模拟中每个未实现的方法提供默认存根。 默认情况下,对于所有返回值的方法,mock 返回 null、空集合或适当的基元/基元包装器值(例如:0、false、... 对于 int/Integer、boolean/Boolean、...)。
因此,当尝试对 的调用进行存根时NumberFormat#format(long),因为它有一个实现,所以您最终会调用NumberFormat#format(long, StringBuffer, FieldPosition)返回的默认存根null,然后将其.toString()进行 -ed 并在那里您得到 NPE 的原因。
通常,您会模拟一个接口,而不是直接模拟一个类,这将完全避免出现此类问题的可能性,因为不会有任何最终的东西。但是,由于这里没有可用于模拟的接口,因此它不是一个选项。
您可以直接模拟 format 的 3-arg 重载:然后它应该允许您根据需要调用 format 的一个参数版本:
@Test
public void test() {
final NumberFormat mockFormatter = mock(NumberFormat.class);
final StringBuffer buffer = new StringBuffer("1");
when(mockFormatter.format(anyLong(), any(StringBuffer.class), any(FieldPosition.class))).thenReturn(buffer);
System.out.println("Result: " + mockFormatter.format(1));
}
Run Code Online (Sandbox Code Playgroud)
但是,我不确定这是最好的解决方案。也许其他人会权衡。
编辑:
看到 Garrett Hall 的回答后,我更明确地表示,当我谈论实现时,我指的是最终实现。
正如他所建议的,如果您愿意走这条路,PowerMock 将允许直接模拟最终的格式方法。
| 归档时间: |
|
| 查看次数: |
2813 次 |
| 最近记录: |