How to mock list method using Mockito

I have a service class which calls Repository method and which returns a List. Now I want to mock it. My unit test scenario would be following:

  • Add some mock objects to mock repository
  • Query service class which returns the list of mocked objects
  • Assert List size

My repository class:

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface FoodRepository extends CrudRepository<Food, Long> {

    @Query(value = "SELECT * FROM FOOD WHERE FRESH = 1", nativeQuery = true)
    public List<Food> getMostFreshestFoods();
}

My service class:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class FoodService {

    @Autowired
    private FoodRepository foodRepository;

    public List<Food> getMostFreshestFoods() {
        return foodRepository.getMostFreshestFoods();
    }
}

My object class:

public class Food {

    private Long id;

    private String foodName;

    private boolean fresh;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFoodName() {
        return foodName;
    }

    public void setFoodName(String foodName) {
        this.foodName = foodName;
    }

    public boolean isFresh() {
        return fresh;
    }

    public void setFresh(boolean fresh) {
        this.fresh = fresh;
    }
}

And my test class:

import myapp.Food;
import myapp.FoodRepository;
import myapp.FoodService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class FoodTest {

    @Mock
    private FoodRepository foodRepository;

    @InjectMocks
    private FoodService foodService;

    @Captor
    private ArgumentCaptor<Food> foodArgumentCaptor;

    @Test
    public void testFreshestFoods() {

        Food food = new Food();
        food.setFoodName("Meat");
        food.setFresh(true);
        foodRepository.save(food);
        verify(foodRepository).save(foodArgumentCaptor.capture());
        assertThat(foodArgumentCaptor.getValue().getId(), is(notNullValue()));

        // Above I added mock data to database to query list from Service class method,
        // but I do not know how to do it. Using return always gives error

        // I want to do the following: Query the list from FoodService class and it should
        // return size 1 (the fake object (added above) )

    }


}

But since I am new to Mockito, it is a bit difficult to me. I would like to know how can I get the list from FoodService class and it should return the fake object made in test class.

Answer

I believe what you are looking for is below. You don’t need to do a normal workflow to test with Mockito. Another way to say is you don’t add things to your DB then expect to get them back. Mockito doesn’t know databases. It takes over a class (the mocked one) and returns things you tell it to or throws exceptions or just does nothing. The idea is to isolate the class under test. So in your case, pretend the data is in the repository and just mock returning it. Hope that makes sense.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.List;

import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class FoodTest {

    @Mock
    private FoodRepository foodRepository;

    @InjectMocks
    private FoodService foodService;

    @Captor
    private ArgumentCaptor<Food> foodArgumentCaptor;

    @Test
    public void testFreshestFoods() {

        Food food = new Food();
        food.setFoodName("Meat");
        food.setFresh(true);

        // not needed
        //foodRepository.save(food);
        //verify(foodRepository).save(foodArgumentCaptor.capture());
        //assertThat(foodArgumentCaptor.getValue().getId(), is(notNullValue()));

        when(foodRepository.getMostFreshestFoods()).thenReturn(asList(food));

        List<Food> actual = foodService.getMostFreshestFoods();

        assertEquals(food, actual.get(0));
        verify(foodRepository).getMostFreshestFoods();
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *