完善章节4单元测试

This commit is contained in:
bwh
2019-04-15 23:14:57 +08:00
parent 5b902de8c1
commit b107d49da3
11 changed files with 335 additions and 7 deletions

View File

@@ -54,7 +54,6 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 模板引擎 Thymeleaf 依赖 -->

View File

@@ -1,12 +1,40 @@
package spring.boot.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import spring.boot.core.domain.User;
import spring.boot.core.domain.UserRepository;
@SpringBootApplication
public class ValidatingFormInputApplication {
public class ValidatingFormInputApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ValidatingFormInputApplication.class, args);
}
private Logger LOG = LoggerFactory.getLogger(ValidatingFormInputApplication.class);
@Autowired
private UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(ValidatingFormInputApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
User user1 = new User("Sergey", 24, "1994-01-01");
User user2 = new User("Ivan", 26, "1994-01-01");
User user3 = new User("Adam", 31, "1994-01-01");
LOG.info("Inserting data in DB.");
userRepository.save(user1);
userRepository.save(user2);
userRepository.save(user3);
LOG.info("User count in DB: {}", userRepository.count());
LOG.info("User with ID 1: {}", userRepository.findById(1L));
LOG.info("Deleting user with ID 2L form DB.");
userRepository.deleteById(2L);
LOG.info("User count in DB: {}", userRepository.count());
}
}

View File

@@ -79,6 +79,15 @@ public class User implements Serializable {
this.birthday = birthday;
}
public User(String name, Integer age, String birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public User() {}
@Override
public String toString() {
return "User{" +

View File

@@ -103,7 +103,7 @@ public class UserController {
/**
* 处理 "/users/{id}" 的 GET 请求,用来删除 User 信息
*/
@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
public String deleteUser(@PathVariable Long id) {
userService.delete(id);

View File

@@ -1,2 +1,15 @@
## 开启 H2 数据库
spring.h2.console.enabled=true
## 配置 H2 数据库连接信息
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
## 是否显示 SQL 语句
spring.jpa.show-sql=true
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create

View File

@@ -0,0 +1,159 @@
package spring.boot.core.web;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.TestPropertySource;
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.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import spring.boot.core.ValidatingFormInputApplication;
import spring.boot.core.domain.User;
import spring.boot.core.service.UserService;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ValidatingFormInputApplication.class)
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application.properties")
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private UserService userService;
@Autowired
private ObjectMapper objectMapper;
@Test
public void getUserList() throws Exception {
mockMvc.perform(get("/users"))
.andExpect(view().name("userList"))
.andExpect(status().isOk())
.andDo(print());
}
private User createUser() {
User user = new User();
user.setName("测试用户");
user.setAge(100);
user.setBirthday("1994-01-01");
return userService.insertByUser(user);
}
@Test
public void createUserForm() throws Exception {
mockMvc.perform(get("/users/create"))
.andDo(print())
.andExpect(view().name("userForm"))
.andExpect(request().attribute("action", "create"))
.andDo(print())
.andReturn();
}
@Test
public void postUser() throws Exception {
User user = createUser();
assertNotNull(user);
MultiValueMap parameters = new LinkedMultiValueMap<String, String>();
Map<String, String> maps = objectMapper.convertValue(user, new TypeReference<Map<String, String>>() {
});
parameters.setAll(maps);
mockMvc.perform(post("/users/create").params(parameters))
.andDo(print())
.andExpect(status().is(HttpServletResponse.SC_FOUND))
.andDo(print())
.andExpect(view().name("redirect:/users/"))
.andDo(print())
.andReturn();
}
@Test
public void getUser() throws Exception {
MvcResult result= mockMvc.perform(get("/users/update/{id}/", 1))
.andExpect(status().isOk())
.andExpect(view().name("userForm"))
.andExpect(MockMvcResultMatchers.model().attributeExists("action"))
.andExpect(model().attribute("user", hasProperty("id", is(1L))))
.andExpect(model().attribute("user", hasProperty("name", is("Sergey"))))
.andExpect(model().attribute("user", hasProperty("age", is(24))))
.andExpect(model().attribute("user", hasProperty("birthday", is("1994-01-01"))))
.andReturn();
MockHttpServletResponse mockResponse=result.getResponse();
assertThat(mockResponse.getContentType()).isEqualTo("text/html;charset=UTF-8");
Collection<String> responseHeaders = mockResponse.getHeaderNames();
assertNotNull(responseHeaders);
assertEquals(2, responseHeaders.size());
assertEquals("Check for Content-Type header", "Accept-Language", responseHeaders.iterator().next());
String responseAsString=mockResponse.getContentAsString();
assertTrue(responseAsString.contains("用户管理"));
}
@Test
public void putUser() throws Exception {
User user = createUser();
assertNotNull(user);
MultiValueMap parameters = new LinkedMultiValueMap<String, String>();
Map<String, String> maps = objectMapper.convertValue(user, new TypeReference<Map<String, String>>() {
});
parameters.setAll(maps);
mockMvc.perform(post("/users/update").params(parameters))
.andDo(print())
.andExpect(status().is(HttpServletResponse.SC_FOUND))
.andDo(print())
.andExpect(view().name("redirect:/users/"))
.andDo(print())
.andReturn();
}
@Test
public void deleteUser() throws Exception {
mockMvc.perform( MockMvcRequestBuilders.delete("/users/delete/{id}", 1L) )
.andDo(print())
.andExpect(status().is(HttpServletResponse.SC_FOUND))
.andExpect(view().name("redirect:/users/"));
}
public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.writeValueAsBytes(object);
}
}

View File

@@ -0,0 +1,14 @@
## 开启 H2 数据库
spring.h2.console.enabled=true
## 配置 H2 数据库连接信息
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
## 是否显示 SQL 语句
spring.jpa.show-sql=true
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create

View File

@@ -0,0 +1,2 @@
/* contentDiv */
.contentDiv {padding:20px 60px;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

View File

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<script type="text/javascript" th:src="@{https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js}"></script>
<link th:href="@{https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css}" rel="stylesheet"/>
<link th:href="@{/css/default.css}" rel="stylesheet"/>
<link rel="icon" th:href="@{/images/favicon.ico}" type="image/x-icon"/>
<meta charset="UTF-8"/>
<title>用户管理</title>
</head>
<body>
<div class="contentDiv">
<h5> 《 Spring Boot 2.x 核心技术实战》第二章快速入门案例</h5>
<legend>
<strong>用户管理</strong>
</legend>
<form th:action="@{/users/{action}(action=${action})}" method="post" class="form-horizontal">
<input type="hidden" name="id" th:value="${user.id}"/>
<div class="form-group">
<label for="user_name" class="col-sm-2 control-label">名称:</label>
<div class="col-xs-4">
<input type="text" class="form-control" id="user_name" name="name" th:value="${user.name}" th:field="*{user.name}" />
</div>
<label class="col-sm-2 control-label text-danger" th:if="${#fields.hasErrors('user.name')}" th:errors="*{user.name}">姓名有误!</label>
</div>
<div class="form-group">
<label for="user_age" class="col-sm-2 control-label">年龄:</label>
<div class="col-xs-4">
<input type="text" class="form-control" id="user_age" name="age" th:value="${user.age}" th:field="*{user.age}" />
</div>
<label class="col-sm-2 control-label text-danger" th:if="${#fields.hasErrors('user.age')}" th:errors="*{user.age}">年龄有误!</label>
</div>
<div class="form-group">
<label for="user_birthday" class="col-sm-2 control-label">出生日期:</label>
<div class="col-xs-4">
<input type="date" class="form-control" id="user_birthday" name="birthday" th:value="${user.birthday}" th:field="*{user.birthday}"/>
</div>
<label class="col-sm-2 control-label text-danger" th:if="${#fields.hasErrors('user.birthday')}" th:errors="*{user.birthday}">生日有误!</label>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input class="btn btn-primary" type="submit" value="提交"/>&nbsp;&nbsp;
<input class="btn" type="button" value="返回" onclick="history.back()"/>
</div>
</div>
</form>
</div>
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<script type="text/javascript" th:src="@{https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js}"></script>
<link th:href="@{https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css}" rel="stylesheet"/>
<link th:href="@{/css/default.css}" rel="stylesheet"/>
<link rel="icon" th:href="@{/images/favicon.ico}" type="image/x-icon"/>
<meta charset="UTF-8"/>
<title>用户列表</title>
</head>
<body>
<div class="contentDiv">
<h5> 《 Spring Boot 2.x 核心技术实战》第二章快速入门案例</h5>
<table class="table table-hover table-condensed">
<legend>
<strong>用户列表</strong>
</legend>
<thead>
<tr>
<th>用户编号</th>
<th>名称</th>
<th>年龄</th>
<th>出生时间</th>
<th>管理</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${userList}">
<th scope="row" th:text="${user.id}"></th>
<td><a th:href="@{/users/update/{userId}(userId=${user.id})}" th:text="${user.name}"></a></td>
<td th:text="${user.age}"></td>
<td th:text="${user.birthday}"></td>
<td><a class="btn btn-danger" th:href="@{/users/delete/{userId}(userId=${user.id})}">删除</a></td>
</tr>
</tbody>
</table>
<div><a class="btn btn-primary" href="/users/create" role="button">创建用户</a></div>
</div>
</body>
</html>