繁体   English   中英

Mockito:测试无效方法会产生InvalidUseOfMatchersException

[英]Mockito : Testing void methods gives InvalidUseOfMatchersException

我在使用两种无效方法时遇到问题。 encouragedVenturesScoring 的评分中,我按照这个答案模拟了一个将要在for循环中循环的arraylist,并且没有模拟该列表,而是传递了一个真实列表并添加了模拟对象。

Mockito在此行上给我一个InvalidUseOfMatchersException

verify(effectList.get(Mockito.anyInt())).execute(playerHandler);

关于此异常,有很多关于SO的问题,我认为这是由于anyInt()造成的。 无论如何我将其更改为

verify(effectList.get(0)).execute(playerHandler);

现在说的是Wanted but not invoked effect.execute(playerHandler) Actually there were zero interactions with this mock

是因为我放了doNothing吗? doNothing().when(effect).execute(playerHandler);


在我的第二种方法militaryStrengthScoring()方法中,有没有一种方法可以跳过第一部分代码,只是测试if..else条件? 什么是测试此方法的最佳方法?

感谢您的时间。

这是要测试的课程

 public class EndGameScoringBaseController implements EndGameScoringHandler {

private static final int[] TERRITORIES_REWARD = {0,0,1,4,10,20};
private static final int[] CHARACTERS_REWARD = {1,3,6,10,15,21};
private static final int RESOURCES_RATE = 5;
private static final int FIRST_MILITARY_REWARD = 5;
private static final int SECOND_MILITARY_REWARD = 2;

private PlayerHandler player;

public EndGameScoringBaseController(PlayerHandler player) {
    super();
    this.player = player;
}

@Override
public void encouragedVenturesScoring() {
    for (DevelopmentCard card : player.getPlayer().getPersonalBoard().getVentures()) {
        for (Effect e : card.getPermanentEffects())
            e.execute(player);
    }
}

@Override
public void militaryStrengthScoring(GameController game) {
    Set<Integer> points = new HashSet<>();
    int myPoints = this.player.getPointsHandler().getMilitaryPoints();

    for (PlayerHandler p: game.getPlayers()) {
        points.add(p.getPointsHandler().getMilitaryPoints());
    }
    int[] rank = new int[points.size()];
    int j = 0;
    for (Integer i : points) {
        rank[j] = i;
        j++;
    }

    Arrays.sort(rank);

    if (rank[rank.length-1] == myPoints) {
        player.getPointsHandler().winMilitaryPoints(FIRST_MILITARY_REWARD);
    }
    else if (rank[rank.length-2] == myPoints) {
        player.getPointsHandler().winVictoryPoints(SECOND_MILITARY_REWARD);
    }

}

鼓励冒险评分的测试方法

@Test
public void encouragedVenturesScoringTest() {
    //given
    List<DevelopmentCard> ventureList;
    ventureList = Arrays.asList(developmentCard, developmentCard);
    when(playerHandler.getPlayer().getPersonalBoard().getVentures()).thenReturn(ventureList);
    List<Effect> effectList;
    effectList = Arrays.asList(effect, effect);
    when(developmentCard.getPermanentEffects()).thenReturn(effectList);
    doNothing().when(effect).execute(playerHandler);

    //when
    endgameController.encouragedVenturesScoring();

    //then
    verify(effectList.get(Mockito.anyInt())).execute(playerHandler);
}

军事实力评分的测试方法不完整

@Test
public void militaryStrengthScoringTest() {

//given     
when(playerHandler.getPointsHandler().getMilitaryPoints()).thenReturn(4);
doNothing().when(playerHandler.getPointsHandler()).winMilitaryPoints(FIRST_MILITARY_REWARD);

//when
endgameController.militaryStrengthScoring(gameController);

//then
/../    
}

您只能验证由Mockito创建的模拟对象。

但是effectList是一个“真实”列表。 因此Mockito对这个对象一无所知。 因此,任何验证该列表的尝试都必须失败。

如果要验证该对象,则必须对其进行模拟!

当然,这意味着您已经指定了将转到模拟列表的所有呼叫。

没错,这就是问题所在:

verify(effectList.get(Mockito.anyInt())).execute(playerHandler);

由于matchers的内部实现, Mockito只允许像any()anyInt()类的调用代表模拟自身的参数。

/*  OK */  when(yourMock.yourMethod(anyInt())).thenReturn(42);
/* BAD */  when(yourList.get(anyInt()).yourMethod(0)).thenReturn(42);

/*  OK */  verify(yourMock).yourMethod(anyInt());
/* BAD */  verify(yourList.get(anyInt())).yourMethod(0);

get(0)的失败很可能是实际的失败,并且可能与您的encouragedVenturesScoringTest的VentureVenturesScoringTest实际上没有调用encouragedVenturesScoring的VentureVenturesScoring有关,而在此情况encouragedVenturesScoring ,它的influencedCharactersScoring是InfluentCharactersScoring。 如果在修正错误后仍继续给您带来麻烦,请使用与Mockito相关的方式,请编辑您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM