java mockito - 检查条件是否通过并调用不返回任何内容的方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17765296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 14:55:03  来源:igfitidea点击:

mockito - checking if condition passes and calls a method which does not return anythig

javamethodsmockitoinvokestub

提问by Kevin Rave

I have the following service class:

我有以下服务类:

 class Person() {

   AgeDAO dao;
   Speaker speaker;

   public method checkSpeak( List<Jon> list) {
        List<Integer> ages = dao.getAge(list);

        if ( ages != null && !ages.isEmpty() ) {
           speaker.speak(list);
        }

   }   

 }

Test class:

测试类:

 @Test
 class MyTest {

    void speakTest() {
        Person p = new Person();
        Speaker speaker = mock(Speaker.class); 
        p.speaker = speaker;

        AgeDAO dao = mock(AgeDAO.class);
        p.dao = dao;

        List<Jon> list = createJonList();
        List<Integer> ages = createAgesList();
        when(dao.getAge(anyList())).thenReturn(ages);
        p.checkSpeak(ages);

        verify(p.speaker).speak(anyList()); // This is not called/invoked.

    }
 }

I just want to verify speakis invoked. Should I still mock the method? If I need to mock the method, how do I mock the method that does not return anything. whenrequires a method return something.

我只想验证是否speak被调用。我还应该嘲笑这个方法吗?如果我需要模拟该方法,我该如何模拟不返回任何内容的方法。when需要一个方法返回一些东西。

回答by Itay Maman

There were a few minor problems in the code you posted (most notably: checkSepaktakes a List<Jon>but your code is passing ageswhich is a List<Integer>).

您发布的代码中存在一些小问题(最明显的是:checkSepak需要 aList<Jon>但您的代码正在通过ages它是 a List<Integer>)。

After fixing these I realized that the test is failing because the ageslist, created by the test (and used as the return value of dao.getAges()), is empty. Thus, the condition ages != null && !ages.isEmpty()is not satisfied which make the code skip over the speaker.speak()call.

解决这些问题后,我意识到测试失败了,因为测试ages创建的列表(并用作 的返回值dao.getAges())是空的。因此,ages != null && !ages.isEmpty()不满足使代码跳过speaker.speak()调用的条件。

The obvious solution is to make the ageslist non-empty by adding some element to it:

显而易见的解决方案是通过向ages列表添加一些元素来使列表非空:

public class MyTest {
  @Test
  public void speakTest() {
    Person p = new Person();
    Speaker speaker = mock(Speaker.class);
    p.speaker = speaker;

    AgeDAO dao = mock(AgeDAO.class);
    p.dao = dao;

    List<Jon> list = createJonList();
    List<Integer> ages = createAgesList();
    ages.add(5);  // Make the list of ages non-empty
    when(dao.getAge(anyList())).thenReturn(ages);
    p.checkSpeak(list);

    verify(p.speaker).speak(anyList());

  }

  private List<Integer> createAgesList() {
    return new ArrayList<Integer>();
  }

  private List<Jon> createJonList() {
    return new ArrayList<Jon>();
  }
}

class Person {
  AgeDAO dao;
  Speaker speaker;

  public void checkSpeak(List<Jon> list) {
    List<Integer> ages = dao.getAge(list);

    if (ages != null && !ages.isEmpty()) {
      speaker.speak(list);
    }
  }
}

回答by mtsui

I don't think you need to mock the object for Speaker since you only used "when" for dao. Unless Speaker has objects that needs to be mocked that would cause the speak method to fail, you should not have to mock Speaker. Try doing p.speaker = new Speaker(); This is the best guess since I'm not sure what Speaker class code looks like.

我认为您不需要为 Speaker 模拟对象,因为您只对 dao 使用了“when”。除非Speaker 有需要模拟的对象会导致speak 方法失败,否则您不应该模拟Speaker。尝试做 p.speaker = new Speaker(); 这是最好的猜测,因为我不确定 Speaker 类代码是什么样的。

回答by manny

You could mock the speak method with doNothing

你可以用doNothing来模拟 speak 方法