How to test listener interface is called within Android Unit Tests

12,604

Here you want to test EventMonitor.doStuff(param) and while executing this method you want to make it sure whether the correct methods on IEventListener were invoked or not.

So, in order to test doStuff(param), you don't need to have a real implementation of IEventListener: what you need is just a mock implementation of IEventListener and you have to verify the exact number of method invocations on IEventListener while testing doStuff. This can be achieved with Mockito or any other mocking framework.

Here is an example with Mockito:

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class EventMonitorTest {

    //This will create a mock of IEventListener
    @Mock
    IEventListener eventListener;

    //This will inject the "eventListener" mock into your "EventMonitor" instance.
    @InjectMocks
    EventMonitor eventMonitor = new EventMonitor();

    @Before
    public void initMocks() {
        //This will initialize the annotated mocks
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() {
        eventMonitor.doStuff(param);
        //Here you can verify whether the methods "doStuff1" and "doStuff2" 
        //were executed while calling "eventMonitor.doStuff". 
        //With "times()" method, you can even verify how many times 
        //a particular method was invoked.
        verify(eventListener, times(1)).doStuff1();
        verify(eventListener, times(0)).doStuff2();
    }

}
Share:
12,604

Related videos on Youtube

CodingIntrigue
Author by

CodingIntrigue

I'm a C#/Javascript Software Developer with a particular interest in front-end frameworks such as Angular & jQuery and the Microsoft stack on the back-end. http://www.codingintrigue.co.uk @CodingIntrigue on Twitter

Updated on June 29, 2022

Comments

  • CodingIntrigue
    CodingIntrigue about 2 years

    I have the following (example) structure within my Android app which I'm trying to write a unit test for:

    class EventMonitor {
      private IEventListener mEventListener;
    
      public void setEventListener(IEventListener listener) {
        mEventListener = listener;
      }
    
      public void doStuff(Object param) {
        // Some logic here
        mEventListener.doStuff1();
        // Some more logic
        if(param == condition) {
          mEventListener.doStuff2();
        }
      }
    }
    

    I want to ensure that when I pass certain values of param, the correct interface methods are called. Can I do this within the standard JUnit framework, or do I need to use an external framework? This is a sample of a unit test I'd like:

    public void testEvent1IsFired() {
      EventMonitor em = new EventMonitor();
      em.setEventListener(new IEventListener() {
        @Override
        public void doStuff1() {
          Assert.assertTrue(true);
        }
    
        @Override
        public void doStuff2() {
          Assert.assertTrue(false);
        }
      });
      em.doStuff("fireDoStuff1");
    }
    

    I'm also a beginner in Java, so if this isn't a good pattern for testing purposes I'm willing to change it to something more testable.