我正在为一个函数写一个单元测试。TestClass
,它检查一个 org.apache.hadoop.hbase.Cell
的内容,并返回enum类型。Enum是以下内容。
public enum Enum_1 {
SKIP,
EXIT_1,
EXIT_2
}
这就是函数。
public ENUM_1 check (Cell cell, String str, int someInt) {
String cellValue = new String(cell.getValueArray(), StandardCharsets.UTF_8);
if(//case 1, doesn't fall here) {
/.../
return SKIP;
}
else if(//case 2, doesn't fall here neither){
/.../
return EXIT_1;
}
//100% sure falls in this case
else {
Long long1 = getLong(str, someInt);
Long long2 = Long.parseLong(cellValue);
if(long1 > long2) {
return EXIT_2;
}
}
return SKIP;
}
在单元测试中,我用mockito做了一个函数。getLong(str, someInt)
返回一定的值。单元测试代码看起来是这样的。
@Test
public void test1() {
TestClass testClass = mock(TestClass.class);
Cell mockCell = mock(Cell.class);
String str = "str";
int someInt = 1;
when(mockCell.getValueArray()).thenReturn("500".getBytes());
when(testClass.getLong(same(str), same(someInt)).thenReturn(Long.valueOf(400));
TestClass.ENUM_1 result = testClass.check(mockCell, str, someInt);
assertEquals(result, TestClass.ENUM_1.SKIP);
}
但是当我运行测试的时候,它的错误是由于 result
被 null
.
再一次,我100%确定通过的值在 else{}
作用 check()
.
问题是:为什么我得到 null
从一个返回值为ENUM类型的函数中取出?我是不是用Mockito做错了什么?感谢任何帮助。
为什么我从一个返回值为ENUM类型的函数中得到空值?
你得到的是null,因为调用的方法返回了null。 在这方面,枚举不是一个特殊的类型;枚举引用可以是空的,就像任何其他对象引用一样。
这是不是我在Mockito上做错了什么?
是的。
看起来你模拟了 实验班,这几乎肯定不是你想要做的(因为这样你就没有在真正的类中测试代码)。 然后你为 getLong()
方法,但是没有告诉模拟人任何关于 check()
方法。
因此,当你调用 testClass.check(mockCell, str, someInt)
,mock采用了默认行为,即返回null。
要解决这个问题,只需要不模拟它就可以了。TestClass
! 构造一个它的实例,所以你的 check()
调用将调用你第二个代码块中显示的实际方法。
为这个答案竖起大拇指! @Andrzej 只是带来了更大的画面。 一般来说,Unite测试执行的是测试一小段代码,通常是一个方法.所以希望被测试的方法不要被嘲讽。所以有这样的概念 存根 即您认为不应该成为单元测试一部分的存根代码。
所以根据原则 getLong()
这个方法的依赖性代表了类似的责任,或者说它在这个功能中扮演了必须的角色。如果是这样,那么它应该是 私人. 如果 getLong()
不应承担这个班级的责任,那么它就应该是其他班级的一部分,因此。单一责任原则 kicks in。
无论这些最佳实践如何,你仍然可以做到这一点,你只需要打电话给我。thenCallRealMethod()
并将其称为 getLong()
从同班同学开始,你必须 谍报 在...上 TestClass
就可以正常工作了。
但我们应该记住 Mockito不允许嘲笑私有和静态方法是有原因的。.快乐的编码!!