您的位置:首页 > 编程语言 > Java开发

009 spring mvc controller unit test

2017-06-09 21:12 501 查看

009 spring mvc controller unit test

视频发布在youtube上面了

https://youtu.be/d-u95Q5JJjs

优酷上面的链接

http://v.youku.com/v_show/id_XMjgxNDY1Nzc4MA==.html?f=49760672

接着008的项目操作。

首先处理一下008中分页显示的时候,500000条记录,页号显示不全的问题。

我这里使用的是themes-default风格。在这里找到easyui.css,里面找到

pagination-num,修改width属性即可。原来是2,我改成了10,顺便了解了一下CSS Units。

em  Relative to the font-size of the element (2em means 2 times the size of the current font)


这里有详细介绍

https://www.w3schools.com/cssref/css_units.asp

.pagination .pagination-num {
border-width: 1px;
border-style: solid;
margin: 0 2px;
padding: 2px;
width: 10em;
height: auto;
}


刷新一下就可以看到变化了。注意如果没有变化清空一下浏览器缓存,在浏览器端检查一下,easyui.css源码是否是修改过后的。

自定义PageList数,非常的方便,设置对应的属性就可以了。

pageSize:12,pageList:[12,100,200,300]

<table id="dg" class="easyui-datagrid" title="用户列表"
style="width: 100%; height: 400px;pagination-num{width:200px}"
data-options="rownumbers:true,striped:true,fitColumns:true,singleSelect:true,autoRowHeight:true,pagination:true,
pageSize:12,pageList:[12,100,200,300],url:'${pageContext.request.contextPath}/getUsers',method:'get',toolbar:'#toolbar'">


TestGetUser增加一个断言判断user是否为空

...
assertTrue(user != null);
assertTrue(user.getName().equals("user1"));


增加测试依赖包

<!-- controller test -->
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path-assert</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>


JsonPath 用来写JSON数据的断言判断的。下面是网址

https://github.com/json-path/JsonPath

新建测试类TestUserController,这里使用实际的service来操作数据库获取数据。

这个用来控制测试函数的执行顺序,添加,更新,删除,执行完毕后,对数据没有影响。

@FixMethodOrder(MethodSorters.NAME_ASCENDING)


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:springmvc.xml")
@WebAppConfiguration
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestUserController
{
public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

private static String lastNewId;

@Before
public void init()
{
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}

@Test
public void testReturnPage() throws Exception
{
mockMvc.perform(get("/users")).andExpect(status().isOk()).andExpect(view().name("users")).andDo(print());
}

@Test
public void testRealApiGetUsers() throws Exception
{
// .accept方法是设置客户端可识别的内容类型
// .contentType,设置请求头中的Content-Type字段,表示请求体的内容类型
mockMvc.perform(get("/getUsers").accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8).param("page", "1").param("rows", "10")).andDo(print())
.andExpect(status().isOk()).andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.total").exists()).andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(10)));
}

@Test
public void test001RealApiAddUser() throws Exception
{
MvcResult ret = mockMvc
.perform(post("/users").accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8).param("name", "user1").param("age", "23")
.param("gender", "女").param("email", "user1@126.com").param("teacherId", "1")
.param("createTime", "2017-06-08 13:59:12").param("loginTime", "2017-06-08 13:59:12"))
.andDo(print()).andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.retCode").value(0)).andExpect(jsonPath("$.newId").exists()).andReturn();
MockHttpServletResponse resp = ret.getResponse();
String strContent = resp.getContentAsString();
JSONObject jsonObject = JSONObject.parseObject(strContent);
lastNewId = jsonObject.get("newId").toString();
}

@Test
public void test002RealApiUpdateUser() throws Exception
{
mockMvc.perform(put("/users/" + lastNewId).accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8).param("name", "user1").param("age", "33")
.param("gender", "男").param("email", "user1@126.com").param("teacherId", "2")
.param("createTime", "2017-06-08 13:59:12").param("loginTime", "2017-06-08 13:59:12"))
.andDo(print()).andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.retCode").value(0)).andExpect(jsonPath("$.status").value("更新成功"));

}

@Test
public void test003RealApiDeleteUser() throws Exception
{
mockMvc.perform(delete("/users/" + lastNewId).accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)).andDo(print()).andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.retCode").value(0)).andExpect(jsonPath("$.status").value("删除成功"));
}
}


在UserController里面做了点修改,添加用户的时候返回了该条记录的主键。顺便把返回类型改成了JSONObject

@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponseBody
public JSONObject addUserProc(User user)
{
// 处理新id生成
// 处理teacher类对象
user.setTeacher(teacherService.getTeacherById(user.getTeacherId()));
int iRet = userService.insertUser(user);
long newId = user.getId();
JSONObject jsonObject = new JSONObject();
if (iRet == 0)
{
logger.info("addUsersProc: " + JSON.toJSON("新建失败:" + JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH:mm:ss")));
jsonObject.put("status", "新建失败");
jsonObject.put("retCode", -1);
} else
{
logger.info("addUsersProc: " + JSON.toJSON("新建用户:" + JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH:mm:ss")));
jsonObject.put("status", "新建成功");
jsonObject.put("retCode", 0);
jsonObject.put("newId", newId);
}
return jsonObject;
}


需要手动引入两个包,不知道为什么不能自动引入。

MethodSorters的作用,这里需求是希望测试函数按照顺序执行,先添加一条记录,获取ID,然后再使用ID删除刚刚添加的记录。

import static org.hamcrest.Matchers.hasSize;
import org.junit.runners.MethodSorters;


现在可以右键-Run As选择JUnit Test

Mock Service测试

新建一个TestUserControllerMockService测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:springmvc.xml")
@WebAppConfiguration
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestUserControllerMockService
{
@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

@InjectMocks
private UserController userController;

@Mock
private IUserService userService;

@Before
public void init()
{
//support @Mock annotation
MockitoAnnotations.initMocks(this);

//解决Controller返回字符串和Mapping字符串相同时提示错误的问题
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");

FastJsonHttpMessageConverter fastjsonMsgConv = this.wac.getBean(com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter.class);
StringHttpMessageConverter stringMsgConv = this.wac.getBean(StringHttpMessageConverter.class);
mockMvc = MockMvcBuilders.standaloneSetup(userController)
.setViewResolvers(viewResolver)
.setMessageConverters(fastjsonMsgConv,stringMsgConv)
.build();
}

@Test
public void testApiGetUsers() throws Exception
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try
{
date = df.parse("2017-06-08 13:59:12");
} catch (ParseException e)
{
e.printStackTrace();
}
List<User> users = new ArrayList<User>();

for (int i = 0; i < 3; ++i)
{
User user = new User();
user.setId(1L + i);
user.setName("user" + Integer.toString(i + 1));
user.setAge(23 + i);
user.setGender("女");
user.setEmail("user1@126.com");
user.setTeacherId(1L);
user.setCreateTime(date);
user.setLoginTime(date);

users.add(user);
}

when(userService.getCount()).thenReturn(3L);
when(userService.getUsersPagenition(1, 3)).thenReturn(users);

mockMvc.perform(get("/getUsers").accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8).param("page", "1").param("rows", "3")).andDo(print())
.andExpect(status().isOk()).andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.total").exists()).andExpect(jsonPath("$.rows").isArray())
.andExpect(jsonPath("$.rows", hasSize(3)))
.andExpect(jsonPath("$.rows[0].name").value("user1"))
.andExpect(jsonPath("$.rows[0].gender").value("女"))
.andExpect(jsonPath("$.rows[0].age").value(23))
.andExpect(jsonPath("$.rows[1].name").value("user2"))
.andExpect(jsonPath("$.rows[1].age").value(24));
//verify Interactions with any mock
verify(userService, times(1)).getCount();
verify(userService, times(1)).getUsersPagenition(1, 3);
verifyNoMoreInteractions(userService);

}
}


@Mock: 需要被Mock的对象

@InjectMocks: 需要将Mock对象注入的对象, 此处就是Controller

下面这个是

MockitoAnnotations.initMocks(this);


@Before

初始化Mock对象, 通过MockMvcBuilders.standaloneSetup模拟一个Mvc测试环境,注入controller, 通过build得到一个MockMvc, 后面就用MockMvc的一些API做测试。

这里面因为使用了fastJson发现之前的springmvc配置需要修改一下,才能通过。暂时先保证学习进度,后面有机会再深入了解一下fastJson的相关配置。

相关错误提示

No qualifying bean of type 'com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter' available


<!-- 对于mvc没有映射过的请求,交给容器默认handler来处理,例如:js,css等静态资源 -->
<mvc:default-servlet-handler />
<!-- FastJson 转换注册 -->
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" index="0"></constructor-arg>
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<!--设置fastjson特性 -->
<property name="features">
<array>
<!--设置null值也要输出,fastjson默认是关闭的 -->
<value>WriteMapNullValue</value>
<!--设置使用文本方式输出日期,fastjson默认是long -->
<value>WriteDateUseDateFormat</value>
</array>
</property>
<property name="fastJsonConfig">
<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="features">
<list>
<value>AllowArbitraryCommas</value>
<value>AllowUnQuotedFieldNames</value>
<value>DisableCircularReferenceDetect</value>
</list>
</property>
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"></property>
</bean>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters register-defaults="true">
<ref bean="stringHttpMessageConverter" />
<ref bean="fastJsonHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>


现在应该可以直接run这个测试了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息