简体   繁体   English

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

[英]Mockito : Testing void methods gives InvalidUseOfMatchersException

I'm having problems with two void methods. 我在使用两种无效方法时遇到问题。 In encouragedVenturesScoring I've followed this answer mocking an arraylist that will be looped in a for loop and haven't mocked the list, but passed a real list and added mocked objects. encouragedVenturesScoring 的评分中,我按照这个答案模拟了一个将要在for循环中循环的arraylist,并且没有模拟该列表,而是传递了一个真实列表并添加了模拟对象。

Mockito gives me an InvalidUseOfMatchersException on this line Mockito在此行上给我一个InvalidUseOfMatchersException

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

There are lots of questions on SO on this exception , and I think it's because of anyInt(). 关于此异常,有很多关于SO的问题,我认为这是由于anyInt()造成的。 Anyway I changed it to 无论如何我将其更改为

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

And now it's saying Wanted but not invoked effect.execute(playerHandler) Actually there were zero interactions with this mock 现在说的是Wanted but not invoked effect.execute(playerHandler) Actually there were zero interactions with this mock

Is it because I put doNothing ? 是因为我放了doNothing吗? doNothing().when(effect).execute(playerHandler);


In my second method militaryStrengthScoring() method is there a way to skip the first chunk of code and just test the if..else condition? 在我的第二种方法militaryStrengthScoring()方法中,有没有一种方法可以跳过第一部分代码,只是测试if..else条件? What would be the best approach to test this method? 什么是测试此方法的最佳方法?

Thank you for your time. 感谢您的时间。

This is the class to be tested 这是要测试的课程

 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);
    }

}

Tested method for encouragedVenturesScoring 鼓励冒险评分的测试方法

@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);
}

Incomplete tested method for militaryStrengthScoring 军事实力评分的测试方法不完整

@Test
public void militaryStrengthScoringTest() {

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

//when
endgameController.militaryStrengthScoring(gameController);

//then
/../    
}

You can only verify mock objects created by Mockito. 您只能验证由Mockito创建的模拟对象。

But effectList is a "real" list. 但是effectList是一个“真实”列表。 Therefore Mockito knows nothing about that object. 因此Mockito对这个对象一无所知。 Thus any attempt to verify that list must fail. 因此,任何验证该列表的尝试都必须失败。

If you want to verify that object - then you have to mock it! 如果要验证该对象,则必须对其进行模拟!

Of course, this means that you have specify all calls that will go to the mocked list. 当然,这意味着您已经指定了将转到模拟列表的所有呼叫。

You're right that this is the problem: 没错,这就是问题所在:

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

Mockito only allows for calls like any() and anyInt() to stand in for parameters to the mock themselves, due to the internal implementation of matchers . 由于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);

The failure with get(0) is likely an actual failure, and may be related to the fact that your encouragedVenturesScoringTest is actually not calling encouragedVenturesScoring , it's calling influencedCharactersScoring . get(0)的失败很可能是实际的失败,并且可能与您的encouragedVenturesScoringTest的VentureVenturesScoringTest实际上没有调用encouragedVenturesScoring的VentureVenturesScoring有关,而在此情况encouragedVenturesScoring ,它的influencedCharactersScoring是InfluentCharactersScoring。 If this continues to give you trouble after fixing that error, in ways related to Mockito, please edit your question. 如果在修正错误后仍继续给您带来麻烦,请使用与Mockito相关的方式,请编辑您的问题。

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

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