Kevin Rave
Kevin Rave

Reputation: 14456

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

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 speak is 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. when requires a method return something.

Upvotes: 0

Views: 19565

Answers (3)

Itay Maman
Itay Maman

Reputation: 30733

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

After fixing these I realized that the test is failing because the ages list, 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.

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

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

Upvotes: 2

manny
manny

Reputation: 162

You could mock the speak method with doNothing

Upvotes: 0

mtsui
mtsui

Reputation: 9

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.

Upvotes: 0

Related Questions