1

My service layer class is like below.

CategoryServiceImpl.java

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private DozerBeanMapper dozerBeanMapper;
    

    @Override
    public CategoryDto createCategory(CategoryDto categoryDto) {

        Category category = categoryRepository.save(dozerBeanMapper.map(categoryDto, Category.class));
        return dozerBeanMapper.map(category, CategoryDto.class);
    }

    @Override
    public List<CategoryDto> findAllCategories() {

        List<Category> all = categoryRepository.findAll();
        return all.stream().map(s -> dozerBeanMapper.map(s, CategoryDto.class)).collect(Collectors.toList());
    }
}

MY Test Class is like below.

import com.os.eprocurement.core.dto.CategoryDto;
import com.os.eprocurement.core.model.Category;
import com.os.eprocurement.repository.CategoryRepository;
import com.os.eprocurement.service.impl.CategoryServiceImpl;
import org.dozer.DozerBeanMapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(MockitoJUnitRunner.class)
public class CategoryServiceTest {


    @InjectMocks
    private CategoryServiceImpl categoryService;

    @Mock
    private CategoryRepository categoryRepository;

    @Mock
    private DozerBeanMapper dozerBeanMapper;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }


    @Test
    public void findAllCategories() {
        Category category = new Category();
        category.setRootCategoryId("345");
        category.setCategoryName("Computers");
        category.setCategoryDescription("PC");
        category.setBusinessUnitId("123");


        CategoryDto categoryDto = new CategoryDto();
        categoryDto.setRootCategoryId("345");
        categoryDto.setCategoryName("Computers");
        categoryDto.setCategoryDescription("PC");
        categoryDto.setBusinessUnitId("123");

        List<Category> categoryList = Arrays.asList(category);

//        List<CategoryDto> categoryDtos = new ArrayList<>();


        when(categoryRepository.findAll()).thenReturn(categoryList);
        when(dozerBeanMapper.map(categoryDto, CategoryDto.class)).thenReturn(categoryDto);

        List<CategoryDto> allCategories = categoryService.findAllCategories();
        assertEquals(1, allCategories.size());
    }


}

It always emit a nullpointer exception when running above Test. But if I use field injection in service layer as below,

CategoryServiceImpl.java

....
@Autowired
public CategoryServiceImpl(CategoryRepository categoryRepository, DozerBeanMapper dozerBeanMapper) {
    this.categoryRepository = categoryRepository;
    this.dozerBeanMapper = dozerBeanMapper;
}
....

and modify Test as below,

CategoryServiceTest.java

...
@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    categoryService = new CategoryServiceImpl(categoryRepository, dozerBeanMapper);
}
...

Test start running fine. But the issue is, since this is a large project and have already used Field Injection in almost everywhere, It is impossible to change it back to Constructor Injection. Are there any way to avoid this NPE while using Field Injection?

I receive NPE from this line,

CategoryServiceTest.java

...
    when(categoryRepository.findAll()).thenReturn(categoryList);
...
techmagister
  • 1,188
  • 8
  • 14

0 Answers0