Как протестировать метод void с помощью весеннего хранилища с использованием Junit и Mockito - PullRequest
0 голосов
/ 21 января 2020

У меня есть java служба Spring, которая вызывает хранилище данных Spring, и я хочу провести тест Junit с mockito, это мой класс и служба, которую я хочу проверить:

@Service
public class DataServiceImpl implements DataService{

    @Autowired
    private CautionRepository cautionRepository;



        @Override
        public void addCautions(List<CautionsDTO> cautions, Contrat contrat) {

            if(cautions != null && !cautions.isEmpty()) {
                cautions.forEach(caution -> {

                        Caution caution = new Caution();

                        cautionContrat.setAmount(caution.getAmount());
                        cautionContrat.setDate(caution.getDate());

                        caution.setContrat(contrat);

                        cautionRepository.save(caution);
            });
            }
        }
    }

и это мой юнит-тест

@RunWith(SpringRunner.class)
public class DataServiceImplTest{

@InjectMocks
private DataServiceImpl dataService;

@Mock
private CautionRepository cautionRepository;

    @Test
    public void addListCautionsTest() {

        List<CautionsDTO> cautions = new ArrayList<>(); 
        ContratExportation contrat = new ContratExportation();

        Caution caution = new Caution();

         dataDelService.addCautions(cautions,contrat);

        Mockito.verify(cautionRepository, times(1)).save(caution);

    }
}

Когда я запускаю тест, у меня появляется следующая ошибка:

Wanted but not invoked:
cautionRepository.save(
    org.model.Caution@2abe9173
);
-> at org.service.DataServiceImplTest.addListCautionsTest(DataServiceImplTest.java:292)
Actually, there were zero interactions with this mock.

Есть ли у вас какие-либо идеи, пожалуйста, в чем ошибка моего теста

Ответы [ 3 ]

1 голос
/ 21 января 2020

Вы никогда не добавляете значение к cautions, поэтому l oop не выполняется и проверка должна завершиться неудачей.

Добавьте значение в список, и тест должен пройти:

    List<CautionsDTO> cautions = new ArrayList<>(); 
    ContratExportation contrat = new ContratExportation();

    CautionDTO caution = new CautionDTO();
    cautions.add(caution);
    dataDelService.addCautions(cautions,contrat);
1 голос
/ 21 января 2020

Прежде всего, вы забыли добавить объект предостережение в список предостережения . Но кроме этого вы смешиваете юнит-тест с интеграционным тестом.

Вам необходимо аннотировать свой тестовый класс с помощью @ RunWith (MockitoJUnitRunner.class) ,

или

Вам необходимо аннотировать ваши фиктивные объекты с помощью @ MockBean и добавить @Autowired в ваш объект класса DataServiceImpl класса тестирования.

Теперь позвольте мне объяснить вам.

Модульный тест

Если вы хотите написать модульный тест, вы не должны использовать контекст приложения (автопровод).

По Кстати, лучшим подходом является аннотирование DataServiceImpl с помощью @RequiredArgsConstructor из Lombok и удаление @Autowired из CautionRepository. Это позволит вам создать экземпляр DataServiceImpl в методе установки в вашем модульном тесте.

Ваш класс DataServiceImpl должен быть:

@Service
@RequiredArgsConstructor
public class DataServiceImpl implements DataService{

    private final CautionRepository cautionRepository;

    @Override
    public void addCautions(List<CautionsDTO> cautions, Contrat contrat) {
        // your code...
    }
}

, а новый класс модульного теста:

@RunWith(MockitoJUnitRunner.class)
public class DataServiceImplTest{

    private DataServiceImpl dataService;

    @Mock
    private CautionRepository cautionRepository;

    @Before
    public void setup() {
        dataService = new DataServiceImpl(cautionsRepository);
    }

    @Test
    public void addListCautionsTest() {
        // your test code...
    }
}

Интеграционный тест

Теперь, если вы хотите создать интеграционный тест , используйте @ RunWith (SpringRunner.class) . При этом ваш прикладной контекст будет загружен. В вашем случае вы можете создать фиктивный бин внутри контекста, пометив свой объект с помощью @ MockBean . Это вставит макетированный объект в ваш контекст и автоматически подключится к вашему реальному классу.

Для этого ваш новый класс DataServiceImpl может остаться таким же, как указано выше. Но измените ваш интеграционный тест на:

@RunWith(SpringRunner.class)
public class DataServiceImplTest{

    @Autowired
    private DataServiceImpl dataService;

    @MockBean // it will be injected automatically
    private CautionRepository cautionRepository;

    @Test
    public void addListCautionsTest() {
        // your test code...
    }
}

Надеюсь, теперь вы понимаете разницу и ошибку, которую вы делали :) 1050 *

0 голосов
/ 21 января 2020

Это должен быть правильный код для выполнения теста

@RunWith(SpringRunner.class)
public class DataServiceImplTest{

@Autowired
private DataServiceImpl dataService;

@MockBean
private CautionRepository cautionRepository;

    @Test
    public void addListCautionsTest() {

        List<CautionsDTO> cautions = new ArrayList<>(); 
        ContratExportation contrat = new ContratExportation();

        Caution caution = new Caution();

         dataDelService.addCautions(cautions,contrat);

        Mockito.verify(cautionRepository, times(1)).save(caution);

    }
}
...