繁体   English   中英

如何在Java中为宁静的Web服务运行简单的junit?

[英]How to run simple junit for restful webservices in java?

我尝试为2种方法运行单元测试。 当我为testRetrieveAllHotels_ServiceLayer()方法运行JUnit测试成功时,但是当我尝试为testRetrieveAllHotels_WebLayer()方法运行JUnit测试时,出现此错误: 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(“ Debugging 1”)放入Controller的retrieveAllHotels()方法中,并将System.out.println(“ Debugging 2”)放入Service的retrieveAllHotels()方法中。 这些仅用于调试。 当我为testRetrieveAllHotels_ServiceLayer()方法运行JUnit测试时,它可以成功运行,但是在控制台中没有得到“ Debugging 2”。

当我为testRetrieveAllHotels_WebLayer()方法运行JUnit测试时,出现java.lang.NullPointerException错误,并且在控制台中出现“调试1”。 我试图了解为什么在第一种情况下没有“ Debugging 2”,以及如何成功运行第二种方法。 任何反馈将不胜感激!

@WebMvcTest我想您正在尝试编写控制器测试,在该测试中您已自动连接MockMvcMockMvc了服务类。

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(); } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM