简体   繁体   中英

Mocking an interface with Mockito

Can someone please help me with the below Mock object. I want to write a mock test case for ServiceImpl class. I want to mock OrderIF interface:

public interface OrderIF{
    List<Order> ordersFor(String type);
}

The implementation of service is:

public class ServiceImpl implements Service {
    private List <Order> orders ;
    private OrderIF orderif ; // this is 3rd party interface

    public int getval(String type) {
       //some code 

       // this returns a list of objects (orders)
       orders = orderif.ordersFor(type);

       // some code 
       return orders.get(0)
    }
}

My code give NullPoinerException:

public class ServiceImplTest {
     private List <Order> ll ;
     private service reqService ; 

     @InjectMocks
     private orderIF order;

     @Before
     public void setUp() throws Exception {
         ll = new ArrayList<Order> ();
         ll.add(new Order("Buy"  ,  11 , "USD" ));
         ll.add(new Order("Sell" ,  22 , "USD" ));
         reqService = spy(new ServiceImpl());
     }

     @Test
     public void test() {
        String type= "USD" ; 
        when(order.ordersFor(type)).thenReturn(ll);
        q = reqService.getval(type);
        assertTrue(q.get().ask == 232.75);
    }
}

@InjectMocks will not instantiate or mock your class. This annotation is used for injecting mocks into this field.

If you want to test serviceImpl you will need to mock in this way:

@Mock
private OrderIF order;

@InjectMocks
private Service reqService = new ServiceImpl(); 

To make it work you either need to use runner or MockitoAnnotations.initMocks(this); in @Before method.

I'm guessing that order is null and you're getting the NullPointerException here:

when(order.ordersFor(type)).thenReturn(ll);

For @InjectMocks to work and instantiate your class, you'll need to add a runner:

@RunWith(MockitoJUnitRunner.class)
public class ServiceImplTest {
    // ...
}

You don't have to use the runner, refer to the documentation for alternatives.

@InjectMocks doesn't work on interface. It needs concrete class to work with.

Also @InjectMocks is used to inject mocks to the specified class and @Mock is used to create mocks of classes which needs to be injected.

So for your case to work you have to do following change

@Mock 
private OrderIF order;

@InjectMocks 
private ServiceImpl reqService;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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