为什么mockMap
使用真正的实现?
我该如何防止这种情况?
方法testFirstKeyMatch
when(mockMap.keySet().toArray()[0])...
在运行测试时抛出ArrayIndexOutOfBoundsException:0。
MaxSizeHashMap 是一个最大大小为7的LinkedHashMap, 当我尝试将更多内容放入时抛出IndexOutOfBoundsException。
个人资料会跟踪对此不重要的事情。
SuperClass.java
public class SuperClass {
protected String[] days;
protected MaxSizeHashMap<String, String> map;
public SuperClass() {
days = new String[7];
map = new MaxSizeHashMap<String, String>();
//...
}
void updateDays() {
cal = Calendar.getInstance();
for (int i = 0; i < 7; i = i + 1) {
//adds short names "Mon", "Tue", ... to days
days[i] = cal.getDisplayName(Calendar.DAY_OF_WEEK,
Calendar.SHORT, Locale.US);
cal.add(Calendar.DATE, 1);
}
}
void firstKeyMatch(Profile profile) {
updateDays();
//checks if first key of map is not same as days[0]
if (days[0] != map.keySet().toArray()[0]) {
profile.add();
//...
}
}
}
SuperClassTest.java
@RunWith(MockitoJUnitRunner.class)
public class SuperClassTest {
@InjectMocks
private SuperClass spr = new SuperClass();
@Mock
private MaxSizeHashMap<String, String> mockMap;
@Mock
private Profile mockProfile;
//...
@Test
public void testFirstKeyMatch() {
when(mockMap.keySet().toArray()[0]).thenReturn(spr.days[0]);
verify(mockProfile, never()).add();
}
}
答案 0 :(得分:3)
根据documentation,模拟的模拟隐含行为是返回default values。
默认情况下,对于返回值的所有方法,mock将根据需要返回null,基元/原始包装器值或空集合。例如0表示int / Integer,false表示布尔值/布尔值。
因此,您的mockMap.keySet()
将返回一个空的哈希集,然后您将其转换为空数组并尝试检索(不存在的)第一个元素,从而检索IOOBE。
总之,mockito没有使用真正的实现,但它的行为正常,因为它应该如此。
您没有发布SuperClass
的整个构造函数,但可能在您实例化地图后,还会使用值填充它。如果这是真的,那么可以说这个例外实际证明了mockito没有使用真正的实现,因为你真的得到了第一个元素。
至于解决方案,已经建议您使用您需要的任何数据返回您自己的哈希集(归功于Abubakkar):
when(mockMap.keySet()).thenReturn(new HashSet(Arrays.asList("your day string")));
答案 1 :(得分:1)
要将所有mockMap.keySet().toArray()[i]
次来电重定向到spr.days[i]
,当有人请求密钥集时,您可以告诉mockMap
返回days
数组。
Set keySetMock = mock(Set.class);
when(keySetMock.toArray()).thenReturn(spr.days);
when(mockMap.keySet()).thenReturn(keySetMock);