Получение исключения NullPointerException при отключении репозитория

#java #spring #nullpointerexception #mockito

#java #весна #исключение nullpointerexception #mockito

Вопрос:

Привет, я пытаюсь написать какой-то тест для своего приложения, но я застрял. Я получаю NPE при отключении моего репозитория, и я не могу понять, почему. Тест бессмыслен, но я хочу понять, что с ним не так. Любая помощь приветствуется 🙂

Репозиторий:

 @Repository
public interface ItemRepository extends CrudRepository<Item, String> {}
 

Обслуживание:

 @Service
public class ItemService {

    @Autowired
    ItemRepository itemRepository;

    @Autowired
    SteamMarketItemService steamMarketItemService;

    public void addItem(Item item) {
        itemRepository.save(item);
    }

    public List<Item> getAllItems() {
        return (List<Item>) itemRepository.findAll();
    }
 

Тест:

 @RunWith(MockitoJUnitRunner.class)
class ItemServiceTest {

    @Mock
    ItemRepository itemRepository;

    @InjectMocks
    ItemService itemService;

    @Test
    void getAllItems_shouldReturnListOfItems() {
        //given
        List<Item> itemList = Collections.singletonList(new Item());
        //when
        when(itemRepository.findAll()).thenReturn(itemList);
        List<Item> returnedItems = itemService.getAllItems();

        //then
        Assert.assertEquals(itemList,returnedItems);
    }
}
 

Ошибка:

 java.lang.NullPointerException
    at itemServiceTest.getAllItems_shouldReturnListOfItems(ItemServiceTest.java:34)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
 

Комментарии:

1. Какая строка равна 34?? Elter itemRepository равно null или ItemService равно null. Зависит от того, что находится в 34. Наверняка он не попадает в метод Service#getAllItems

2. похоже, что mocks не вводятся в ItemService

3. @Deadpool я не думаю, что выполнение заходит так далеко.

4. when(itemRepository.findAll()).thenReturn(itemList); это проблема, я пытался выполнить только when(itemRepository.findAll()) , но результат тот же

5. Судя по классу, вы запускаете тест с JUnit5, а не с JUnit 4. Делает runner бесполезным. Либо используйте JUnit5 правильно, либо JUnit4, теперь у вас есть гибрид, который не будет работать.

Ответ №1:

Возможно, вам потребуется использовать MockitoExtension

@Mocks являются зависимостями от вашей @InjectMocks ссылки. В этом случае ваши аннотации к сервису и репозиторию верны.

Вот как я могу решить эту проблему при использовании JUnit5

 package com.example.demo;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

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

import static org.mockito.ArgumentMatchers.any;

@ExtendWith(MockitoExtension.class)
class ItemServiceTests {

    @InjectMocks
    ItemService itemService;

    @Mock
    ItemRepository itemRepository;


    @Test
    void testItemServiceSaveItem() {
        Item item = new Item(312, "Test Mock");
        Mockito.when(itemRepository.save(item)).thenReturn(item);
        final Item saveItem = itemService.addItem(item);
        Mockito.verify(itemRepository, Mockito.times(1)).save(any(Item.class));
        Assertions.assertNotNull(saveItem, "Saved object cannot be null");
        Assertions.assertEquals(312, item.getId());
    }

    @Test
    void testGetItemListSuccess() {
        //given
        List<Item> itemList = Collections.singletonList(new Item());
        //when
        Mockito.when(itemRepository.findAll()).thenReturn(itemList);
        List<Item> returnedItems = itemService.getAllItems();
        //then
        Assertions.assertEquals(itemList, returnedItems);
    }

    @Test
    void testGetItemListFailure() {
        //given
        List<Item> itemList = Collections.singletonList(new Item());
        //when
        Mockito.when(itemRepository.findAll()).thenReturn(Arrays.asList(
                new Item(),
                new Item()
        ));
        List<Item> returnedItems = itemService.getAllItems();
        //then
        Assertions.assertNotEquals(itemList, returnedItems);
    }
    
}