项目场景:
项目场景:在对控制层使用(powermockito+junit+mockmvc)做单元测试,出现版本兼容性bug
问题描述:
对查询设备历史状态的接口进行单元测试时,代码一切正常,控制台打印无报错,junit显示报错。
测试代码如下:
package com.fotile.cloud.controller;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import com.fotile.cloud.admin.idc.request.IDCDeviceInfo;
import com.fotile.cloud.controller.support.SpringJunit4MockSupport;
import com.fotile.cloud.entity.tsl.DataTypeDes;
import com.fotile.cloud.entity.tsl.ProductAtTSL;
import com.fotile.cloud.entity.tsl.TSLPropertyDetail;
import com.fotile.cloud.facade.tsl.TSLService;
import com.google.gson.Gson;
@PrepareForTest({ IDCControllerTest.class })
public class IDCControllerTest extends SpringJunit4MockSupport
{
@Resource
private ApplicationContext context;
Gson gson = new Gson();
private HttpHeaders getHeaders()
{
String token = "0nIilFSQ50R0hkQKhXbiFUVvtmewxEeutEOiojIt9GZuFmciwiI4JiOi02bk5WYSBHchJCLiQjM5YmNyYGO1kjM0MTZlJGZmRDN3gTYycDZ2AjZhJzMiojIklmIsIiNwIiOiUGc5RnI7ZDM="; // TODO
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Access-Token", token);
httpHeaders.set("Content-Type", "application/json");
return httpHeaders;
}
@Test
public void testHistoryStatusInfo() throws Exception
{
TSLService tSLService = context.getBean(TSLService.class);
// 准备预判返回情况
String productId = getRequestParm().getProductId();
PowerMockito.when(tSLService.getProductTSLRelation(productId)).thenReturn(getProductAtTSL());
PowerMockito
.when(tSLService.getTSLPropertyInfo(getProductAtTSL().getTslId(), getRequestParm().getPropertyName()))
.thenReturn(getTSLPropertyDetail());
// 模拟请求
String json = gson.toJson(getRequestParm());
String url = "/product/historyStatusInfo";
MockHttpServletRequestBuilder content = MockMvcRequestBuilders.post(url).headers(getHeaders()).content(json)
.contentType(MediaType.APPLICATION_JSON);
ResultActions resultActions = mockmvc.perform(content);
resultActions.andExpect(status().isOk()).andDo(MockMvcResultHandlers.print()).andReturn();
}
// 准备请求参数
private IDCDeviceInfo getRequestParm()
{
String productId = "e3239b118f9af0b46f1409064aecb0aa";
String startDay = "2020-04-01";
String endDay = "2020-04-30";
String propertyName = "故障号";
Integer statusNum = 0;
Integer pageSize = 10;
Integer pageNum = 1;
String order = "desc";
return new IDCDeviceInfo(productId, startDay, endDay, propertyName, statusNum, pageNum, pageSize, order);
}
// 准备内部方法返回数据ProductAtTSL
private ProductAtTSL getProductAtTSL()
{
int id = 115;
String productId = "e3239b118f9af0b46f1409064aecb0aa";
Long tslId = 5100000164L; // TODO
ProductAtTSL productAtTSL = new ProductAtTSL();
productAtTSL.setId(id);
productAtTSL.setProductId(productId);
productAtTSL.setTslId(tslId);
return productAtTSL;
}
// 准备内部方法返回数据TSLPropertyDetail
private TSLPropertyDetail getTSLPropertyDetail()
{
List<DataTypeDes> list = new ArrayList<DataTypeDes>();
DataTypeDes dataTypeDes = new DataTypeDes();
dataTypeDes.setValue(0);
dataTypeDes.setName("无异常");
list.add(dataTypeDes);
TSLPropertyDetail tslPropertyDetail = new TSLPropertyDetail();
tslPropertyDetail.setDataSpecs(list);
String identifier = "ErrorNum";
tslPropertyDetail.setIdentifier(identifier);
return tslPropertyDetail;
}
报错如下:
原因分析:
这种报错为servlet版本和spring的版本兼容问题
Spring V4.1.0+的版本在不支持Servlet3.0的应用服务器上跑时会报以下错误:
NoSuchMethodError: javax.servlet.http.HttpServletResponse.getStatus()I
比如说:tomcat 7以下的版本、jboss 4.2.3以下的版本
此时我的Tomcat未被build path引入使用的是eclipse自带的servlet 版本较低
解决方案:
引入tomcat