调用RESTAPI的Spring MVC控制器的错误单元测试

调用RESTAPI的Spring MVC控制器的错误单元测试,spring,spring-mvc,spring-restcontroller,spring-mvc-test,Spring,Spring Mvc,Spring Restcontroller,Spring Mvc Test,我正在我的小应用程序中对spring MVC控制器进行单元测试,但出现以下错误: INFO: **Initializing Spring FrameworkServlet ''** Oct 30, 2015 5:37:38 PM org.springframework.test.web.servlet.TestDispatcherServlet initServletBean INFO: FrameworkServlet '': initialization started Oct 30, 20

我正在我的小应用程序中对spring MVC控制器进行单元测试,但出现以下错误:

INFO: **Initializing Spring FrameworkServlet ''**
Oct 30, 2015 5:37:38 PM org.springframework.test.web.servlet.TestDispatcherServlet initServletBean
INFO: FrameworkServlet '': initialization started
Oct 30, 2015 5:37:38 PM org.springframework.test.web.servlet.TestDispatcherServlet initServletBean
INFO: FrameworkServlet '': initialization completed in 2 ms
Running com.sky.testmvc.product.controller.ProductSelectionControllerTest
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.031 sec <<< FAILURE!
testRoot(com.sky.testmvc.product.controller.ProductSelectionControllerTest)  Time elapsed: 0.031 sec  <<< FAILURE!
*java.lang.AssertionError: **Status expected:<200> but was:<204>***
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
    at org.springframework.test.web.servlet.result.StatusResultMatchers$5.match(StatusResultMatchers.java:549)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:141)
如前所述,应用程序可以工作,我可以读取通过浏览器返回的json及其在我的angularjs视图中的显示,但单元测试不起作用。错误为java.lang.AssertionError:应为状态:但为:。 204-响应为空。。。 是否可以>初始化Spring FrameworkServlet“”,即框架servlet未初始化?不确定。 任何帮助都将不胜感激

我的休息管理员

@RestController 公共类ItemRestController{

@Autowired
ItemService catalogueService;  //Service which will do product retrieval

@Autowired
LocationService locationService;  //Service which will retrieve customer location id using customer id

//-------------------Retrieve All Customer Products--------------------------------------------------------

@RequestMapping(value = "/product/{customerId}", produces = {MediaType.APPLICATION_JSON_VALUE}, method = RequestMethod.GET)
public ResponseEntity<List<Product>> listCustomerProducts(@PathVariable("customerId") int customerId) {

    Integer customerLocation=(Integer) locationService.findLocationByCustomerId(customerId);
    List<Product> products = catalogueService.findCustomerProducts(customerLocation);

    if(products.isEmpty()){
        return new ResponseEntity<List<Product>>(HttpStatus.NO_CONTENT);
    }
    return new ResponseEntity<List<Product>>(products, HttpStatus.OK);
}
@Autowired
ItemService CataloseService;//将执行产品检索的服务
@自动连线
LocationService LocationService;//将使用客户id检索客户位置id的服务
//-------------------检索所有客户产品--------------------------------------------------------
@RequestMapping(value=“/product/{customerId}”,products={MediaType.APPLICATION\u JSON\u value},method=RequestMethod.GET)
公共响应列表CustomerProducts(@PathVariable(“customerId”)int customerId){
整数customerLocation=(整数)locationService.findLocationByCustomerId(customerId);
列表产品=目录服务。查找客户产品(customerLocation);
if(products.isEmpty()){
返回新的响应属性(HttpStatus.NO_内容);
}
返回新响应(产品,HttpStatus.OK);
}

}

正如我们从堆栈跟踪中看到的,由于断言错误,测试失败:它期望HTTP状态
200
,但得到
204
,即
HTTPStatus。无内容
,当列表为空时,您在控制器中返回该内容

        if(products.isEmpty()){
            return new ResponseEntity<List<Product>>(HttpStatus.NO_CONTENT);
        }
if(products.isEmpty()){
返回新的响应属性(HttpStatus.NO_内容);
}

如果你想让你的控制器返回200,你需要你的
catalogeservice
mock来返回一些东西…

在你的测试中,你正在模拟
ItemService
(使用
productServiceMock
),但是你的控制器正在调用
catalogeservice
的实例


还要确保您的模拟被正确注入,调试器确实是您最好的朋友。我猜从你的语法来看,你在使用Mockito。在这种情况下,模拟对象在其
getClass().getName()
方法中有“$$EnhancedByMockito”

您正在测试的控制器是什么样子的?嗨,Kejml,我已经用控制器更新了原始帖子。谢谢,这可能会引出一个很长的问题。显然,您的目录服务返回空结果。服务从哪里获取数据?某种数据库?典型的设置是,普通上下文使用独立于测试上下文的数据库(HSQL是测试的常用选择),所以您必须确保测试数据库包含一些测试数据。这可以在数据库启动期间/打开连接时执行,也可以在测试的@Before/@BeforeClass注释方法中执行。或者您可以模拟服务,这取决于您是在单元测试还是集成测试之后执行……我已更新了测试类中的testRoot()。响应是从硬编码列表中填充的。我已经试过很多次了,我的错。但是,它仍然给了我一个204。我已经在测试类中更新了testRoot()。响应是从硬编码列表中填充的。我已经试过很多次了,我的错。但是,它仍然给了我一个204。t问题是,
产品
是否为空,如果是,为什么。。。这就是调试器的用途…它的ItemService一直都是。这只是一个打字错误时,试图谨慎!很抱歉模拟注射了吗?正如我所说,调试器可以告诉你。。。或者使用普通的old
System.out.println()
ItemControllerTest中的以下行在(productServiceMock.findCustomerProducts(1L))时填充mock>>。然后返回(Arrays.asList(prod1,prod2));如何测试是否注入了模拟。我是模拟测试的新手,因此会问一些愚蠢的问题。不,不,我的意思是在测试期间在控制器中。您能在控制器中放置断点并检查CatalogService实例的类名吗?
@Autowired
ItemService catalogueService;  //Service which will do product retrieval

@Autowired
LocationService locationService;  //Service which will retrieve customer location id using customer id

//-------------------Retrieve All Customer Products--------------------------------------------------------

@RequestMapping(value = "/product/{customerId}", produces = {MediaType.APPLICATION_JSON_VALUE}, method = RequestMethod.GET)
public ResponseEntity<List<Product>> listCustomerProducts(@PathVariable("customerId") int customerId) {

    Integer customerLocation=(Integer) locationService.findLocationByCustomerId(customerId);
    List<Product> products = catalogueService.findCustomerProducts(customerLocation);

    if(products.isEmpty()){
        return new ResponseEntity<List<Product>>(HttpStatus.NO_CONTENT);
    }
    return new ResponseEntity<List<Product>>(products, HttpStatus.OK);
}
        if(products.isEmpty()){
            return new ResponseEntity<List<Product>>(HttpStatus.NO_CONTENT);
        }