Как запустить простой Junit для спокойных веб-сервисов в Java? - PullRequest
0 голосов
/ 09 октября 2018

Я пытаюсь запустить модульные тесты для 2 методов.Когда я запускаю JUnit test для testRetrieveAllHotels_ServiceLayer() метода, он работает успешно, но когда я пытаюсь запустить JUnit test для testRetrieveAllHotels_WebLayer() метода, я получаю эту ошибку: java.lang.NullPointerException

Это код:

package com.xxx.restfultesting.controller;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.Arrays;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import com.xxx.restfultesting.business.HotelBusinessService;
import com.xxx.restfultesting.model.Hotel;

@RunWith(SpringRunner.class)             
@WebMvcTest(HotelController.class)  
public class HotelControllerTest {

    @Autowired
    private MockMvc mockMvc;    

    @MockBean
    private HotelBusinessService businessService;

    @Test
    public void testRetrieveAllHotels_ServiceLayer(){

        businessService.retrieveAllHotels();

        verify(businessService, times(1)).retrieveAllHotels();
    }

    @Test
    public void testRetrieveAllHotels_WebLayer(){

        HotelController hotelController = new HotelController();

        when(businessService.retrieveAllHotels()).thenReturn(               
                Arrays.asList(new Hotel(1, "Sofitel", 120, 20),
                        new Hotel(2, "Ibis", 50, 40),
                        new Item(3, "Marriot", 200, 15)));

        hotelController.retrieveAllHotels();

        verify(businessService, times(1)).retrieveAllHotels();
    }

HotelController:

package com.xxx.restfultesting.controller;

import java.net.URI;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import com.xxx.restfultesting.business.HotelBusinessService;
import com.xxx.restfultesting.model.Hotel;

@RestController
public class HotelController {

    @Autowired
    private HotelBusinessService businessService;

    @GetMapping("/items")
    public List<Hotel> retrieveAllHotels() {

        System.out.println("Debugging 1"); 

        List<Hotel> hotels = businessService.retrieveAllHotels();

        return hotels; 
    }

HotelBusinessService:

package com.xxx.restfultesting.business;

import java.util.List;
import java.util.Optional;

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

import com.xxx.restfultesting.data.HotelRepository;
import com.xxx.restfultesting.model.Hotel;

@Component
public class HotelBusinessService {

    @Autowired
    private HotelRepository repository;

    public List<Hotel> retrieveAllHotels() {

        System.out.println("Debugging 2");

        List<Hotel> hotels = repository.findAll(); 

        return hotels;  
    }
}

Я поместил System.out.println («Отладка 1») внутри метода retrieveAllHotels ()из Controller и System.out.println («Отладка 2») внутри метода retrieveAllHotels () из Service.Это только для отладки.Когда я запускаю тест JUnit для метода testRetrieveAllHotels_ServiceLayer (), он работает успешно, но в консоли не отображается «Отладка 2».

Когда я запускаю тест JUnit для метода testRetrieveAllHotels_WebLayer (), я получаю ошибку java.lang.NullPointerException и получаю сообщение «Отладка 1» в консоли.Я пытаюсь понять, почему нет «Отладки 2» в первом случае и как успешно запустить второй метод.Любая обратная связь будет оценена!

1 Ответ

0 голосов
/ 09 октября 2018

@WebMvcTest - Я думаю, что вы пытаетесь написать тест контроллера, где вы автоматически подключили MockMvc и высмеяли класс обслуживания.

В тесте testRetrieveAllHotels_ServiceLayer вы пытаетесь вызвать метод, который находится в классе проверяемого сервиса, и проверить, был ли вызван этот метод.Тест пройдет успешно, так как вы вызвали макет в самом тесте.

В тесте testRetrieveAllHotels_WebLayer вы создали свой собственный экземпляр контроллера и используете поддельную службу.Чтобы исправить это, вы должны Autowire контроллер в тесте или использовать инжекцию на основе конструктора в классе и передать макет конструктору в тесте

Это только исправит тест, но это не правильный путьпроверить контроллер.Что нужно исправить:

  • Нет необходимости в тесте testRetrieveAllHotels_ServiceLayer.Вы можете удалить этот тест.
  • testRetrieveAllHotels_WebLayer необходимо обновить, как показано ниже:

    public void testRetrieveAllHotels_WebLayer(){
    
      when(businessService.retrieveAllHotels()).thenReturn(
            Arrays.asList(new Hotel(1, "Sofitel", 120, 20),
                    new Hotel(2, "Ibis", 50, 40),
                    new Item(3, "Marriot", 200, 15)));
    
      mockMvc.perform(
            get("/items"))
            .andExpect(status().isOk());
    
      verify(businessService, times(1)).retrieveAllHotels();
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...