Java 使用真实实现的Mockito模拟对象

Java 使用真实实现的Mockito模拟对象,java,junit,mockito,Java,Junit,Mockito,为什么mockMap使用真正的实现? 我如何防止这种情况 在方法testFirstKeyMatch中 when(mockMap.keySet().toArray()[0])... 运行测试时抛出ArrayIndexOutOfBoundsException:0 MaxSizeHashMap是最大大小为7的LinkedHashMap, 当我尝试将更多内容放入时抛出IndexOutOfBoundsException 个人资料记录一些对此不重要的信息 超类.java public class Supe

为什么
mockMap
使用真正的实现? 我如何防止这种情况

在方法testFirstKeyMatch中

when(mockMap.keySet().toArray()[0])...
运行测试时抛出ArrayIndexOutOfBoundsException:0

MaxSizeHashMap是最大大小为7的LinkedHashMap, 当我尝试将更多内容放入时抛出IndexOutOfBoundsException

个人资料记录一些对此不重要的信息

超类.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();

        //...
     }
 }
 }
公共类超类{
受保护字符串[]天;
受保护的MaxSizeHashMap地图;
公共超类(){
天=新字符串[7];
map=新的MaxSizeHashMap();
//...
}
void updateDays(){
cal=Calendar.getInstance();
对于(int i=0;i<7;i=i+1){
//将短名称“Mon”、“Tue”和…添加到天
days[i]=cal.getDisplayName,
Calendar.SHORT,Locale.US);
计算添加(日历日期,1);
}
}
void firstKeyMatch(配置文件){
updateDays();
//检查映射的第一个键是否与天[0]不同
如果(天[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();

}
}
@RunWith(MockitoJUnitRunner.class)
公共类超类测试{
@注射模拟
私有超类spr=新超类();
@嘲弄
私有MaxSizeHashMap mockMap;
@嘲弄
个人档案;
//...
@试验
public void testFirstKeyMatch(){
when(mockMap.keySet().toArray()[0]),然后return(spr.days[0]);
验证(mockProfile,never())。添加();
}
}

要将所有
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);
根据,mockito对于mock的隐式行为是返回

默认情况下,对于所有返回值的方法,mock将根据需要返回null、基元/基元包装器值或空集合。例如,0表示int/Integer,false表示boolean/boolean

因此,您的
mockMap.keySet()
将返回一个空哈希集,然后将其转换为空数组并尝试检索(不存在的)第一个元素,从而检索IOOBE

总之,mockito并没有使用真正的实现,但它的行为正常

您没有发布
超类
的整个构造函数,但可能在实例化映射之后,您也会用值填充它。如果这是真的,那么可以说异常实际上证明了mockito没有使用真正的实现,因为您将真正获得第一个元素

至于解决方案,已经有人建议返回您自己的哈希集,其中包含您所需的任何数据(积分归Abubakkar):


在(mockMap.keySet())时尝试此
,然后返回(新的HashSet(Arrays.asList(“您的日期字符串”))通过将“your day string”替换为您正在测试的任何值,mock将返回默认值。对于
keySet()
,它是一个空集合。
when(mockMap.keySet()).thenReturn(new HashSet(Arrays.asList("your day string")));