diff --git a/lab-42/lab-42-demo01/pom.xml b/lab-42/lab-42-demo01/pom.xml
new file mode 100644
index 00000000..d2a1a646
--- /dev/null
+++ b/lab-42/lab-42-demo01/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.2.RELEASE
+
+
+ 4.0.0
+
+ lab-42-demo01
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ mysql
+ mysql-connector-java
+ 5.1.46
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
+
+
+
diff --git a/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/Application.java b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/Application.java
new file mode 100644
index 00000000..b96d4d52
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/Application.java
@@ -0,0 +1,13 @@
+package cn.iocoder.springboot.lab23.testdemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/controller/UserController.java b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/controller/UserController.java
new file mode 100644
index 00000000..db349d20
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/controller/UserController.java
@@ -0,0 +1,33 @@
+package cn.iocoder.springboot.lab23.testdemo.controller;
+
+import cn.iocoder.springboot.lab23.testdemo.dataobject.UserDO;
+import cn.iocoder.springboot.lab23.testdemo.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 用户 Controller
+ */
+@RestController
+@RequestMapping("/user")
+public class UserController {
+
+ @Autowired
+ private UserService userService;
+
+ /**
+ * 获得指定用户编号的用户
+ *
+ * @param id 用户编号
+ * @return 用户
+ */
+ @GetMapping("/get") // URL 修改成 /get
+ public UserDO get(@RequestParam("id") Integer id) {
+ // 查询并返回用户
+ return userService.get(id);
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/dao/UserDao.java b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/dao/UserDao.java
new file mode 100644
index 00000000..7134114d
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/dao/UserDao.java
@@ -0,0 +1,21 @@
+package cn.iocoder.springboot.lab23.testdemo.dao;
+
+import cn.iocoder.springboot.lab23.testdemo.dataobject.UserDO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class UserDao {
+
+ @Autowired
+ private JdbcTemplate template;
+
+ public UserDO selectById(Integer id) {
+ return template.queryForObject("SELECT id, username, password FROM t_user WHERE id = ?",
+ new BeanPropertyRowMapper<>(UserDO.class), // 结果转换成对应的对象
+ id);
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/dataobject/UserDO.java b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/dataobject/UserDO.java
new file mode 100644
index 00000000..d22dbf84
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/dataobject/UserDO.java
@@ -0,0 +1,50 @@
+package cn.iocoder.springboot.lab23.testdemo.dataobject;
+
+/**
+ * 用户 DO
+ */
+public class UserDO {
+
+ /**
+ * 用户编号
+ */
+ private Integer id;
+ /**
+ * 账号
+ */
+ private String username;
+ /**
+ * 密码(明文)
+ *
+ * ps:生产环境下,千万不要明文噢
+ */
+ private String password;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public UserDO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public UserDO setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public UserDO setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/service/UserService.java b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/service/UserService.java
new file mode 100644
index 00000000..df933852
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/main/java/cn/iocoder/springboot/lab23/testdemo/service/UserService.java
@@ -0,0 +1,18 @@
+package cn.iocoder.springboot.lab23.testdemo.service;
+
+import cn.iocoder.springboot.lab23.testdemo.dao.UserDao;
+import cn.iocoder.springboot.lab23.testdemo.dataobject.UserDO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserService {
+
+ @Autowired
+ private UserDao userDao;
+
+ public UserDO get(Integer id) {
+ return userDao.selectById(id);
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/main/resources/application.yaml b/lab-42/lab-42-demo01/src/main/resources/application.yaml
new file mode 100644
index 00000000..00f6e885
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/main/resources/application.yaml
@@ -0,0 +1,10 @@
+spring:
+ application:
+ name: demo-application
+
+ # datasource 数据源配置内容
+ datasource:
+ url: jdbc:mysql://127.0.0.1:3306/lab-39-mysql?useSSL=false&useUnicode=true&characterEncoding=UTF-8
+ driver-class-name: com.mysql.jdbc.Driver
+ username: root
+ password:
diff --git a/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/controller/UserControllerTest.java b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/controller/UserControllerTest.java
new file mode 100644
index 00000000..b2bb3c73
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/controller/UserControllerTest.java
@@ -0,0 +1,56 @@
+package cn.iocoder.springboot.lab23.testdemo.controller;
+
+import cn.iocoder.springboot.lab23.testdemo.dataobject.UserDO;
+import cn.iocoder.springboot.lab23.testdemo.service.UserService;
+import org.hamcrest.core.IsEqual;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+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.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+/**
+ * UserController 单元测试
+ */
+@RunWith(SpringRunner.class)
+@WebMvcTest(UserController.class)
+public class UserControllerTest {
+
+ @Autowired
+ private MockMvc mvc;
+
+ @MockBean
+ private UserService userService;
+
+ @Test
+ public void testGet() throws Exception {
+ // Mock UserService 的 get 方法
+ Mockito.when(userService.get(1)).thenReturn(
+ new UserDO().setId(1).setUsername("username:1").setPassword("password:1"));
+
+ // 查询用户
+ ResultActions resultActions = mvc.perform(MockMvcRequestBuilders.get("/user/get?id=1"));
+
+ // 校验妆容泰马
+ resultActions.andExpect(MockMvcResultMatchers.status().isOk()); // 响应状态码 200
+
+ // 校验响应内容方式一:直接全部匹配
+ resultActions.andExpect(MockMvcResultMatchers.content().json("{\n" +
+ " \"id\": 1,\n" +
+ " \"username\": \"username:1\",\n" +
+ " \"password\": \"password:1\"\n" +
+ "}", true)); // 响应结果
+
+ // 校验响应内容方式二:逐个字段匹配
+ resultActions.andExpect(MockMvcResultMatchers.jsonPath("id", IsEqual.equalTo(1)));
+ resultActions.andExpect(MockMvcResultMatchers.jsonPath("username", IsEqual.equalTo("username:1")));
+ resultActions.andExpect(MockMvcResultMatchers.jsonPath("password", IsEqual.equalTo("password:1")));
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/dao/UserDaoTest.java b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/dao/UserDaoTest.java
new file mode 100644
index 00000000..081da10e
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/dao/UserDaoTest.java
@@ -0,0 +1,33 @@
+package cn.iocoder.springboot.lab23.testdemo.dao;
+
+import cn.iocoder.springboot.lab23.testdemo.dataobject.UserDO;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.jdbc.Sql;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserDaoTest {
+
+ @Autowired
+ private UserDao userDao;
+
+ @Test
+ @Sql(scripts = "/sql/create_tables.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
+ @Sql(statements = "INSERT INTO `t_user`(`id`, `username`, `password`) VALUES (1, 'username:1', 'password:1');", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
+ @Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
+ public void testSelectById() {
+ // 查询用户
+ UserDO user = userDao.selectById(1);
+
+ // 校验结果
+ Assert.assertEquals("编号不匹配", 1, (int) user.getId());
+ Assert.assertEquals("用户名不匹配", "username:1", user.getUsername());
+ Assert.assertEquals("密码不匹配", "password:1", user.getPassword());
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/package-info.java b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/package-info.java
new file mode 100644
index 00000000..ae8ba9d6
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/package-info.java
@@ -0,0 +1 @@
+package cn.iocoder.springboot.lab23.testdemo;
diff --git a/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/service/UserServiceTest.java b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/service/UserServiceTest.java
new file mode 100644
index 00000000..25b9d120
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/test/java/cn/iocoder/springboot/lab23/testdemo/service/UserServiceTest.java
@@ -0,0 +1,39 @@
+package cn.iocoder.springboot.lab23.testdemo.service;
+
+import cn.iocoder.springboot.lab23.testdemo.dao.UserDao;
+import cn.iocoder.springboot.lab23.testdemo.dataobject.UserDO;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserServiceTest {
+
+ @MockBean
+ private UserDao userDao;
+
+ @Autowired
+ private UserService userService;
+
+ @Test
+ public void testGet() {
+ // Mock UserDao 的 selectById 方法
+ Mockito.when(userDao.selectById(1)).thenReturn(
+ new UserDO().setId(1).setUsername("username:1").setPassword("password:1"));
+
+ // 查询用户
+ UserDO user = userService.get(1);
+
+ // 校验结果
+ Assert.assertEquals("编号不匹配", 1, (int) user.getId());
+ Assert.assertEquals("用户名不匹配", "username:1", user.getUsername());
+ Assert.assertEquals("密码不匹配", "password:1", user.getPassword());
+ }
+
+}
diff --git a/lab-42/lab-42-demo01/src/test/resources/application.yaml b/lab-42/lab-42-demo01/src/test/resources/application.yaml
new file mode 100644
index 00000000..118cef21
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/test/resources/application.yaml
@@ -0,0 +1,10 @@
+spring:
+ application:
+ name: demo-application
+
+ # datasource 数据源配置内容
+ datasource:
+ url: jdbc:h2:mem:testdb
+ driver-class-name: org.h2.Driver
+ username: sa
+ password:
diff --git a/lab-42/lab-42-demo01/src/test/resources/sql/clean.sql b/lab-42/lab-42-demo01/src/test/resources/sql/clean.sql
new file mode 100644
index 00000000..be125207
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/test/resources/sql/clean.sql
@@ -0,0 +1 @@
+DROP TABLE `t_user`
diff --git a/lab-42/lab-42-demo01/src/test/resources/sql/create_tables.sql b/lab-42/lab-42-demo01/src/test/resources/sql/create_tables.sql
new file mode 100644
index 00000000..82c92d7e
--- /dev/null
+++ b/lab-42/lab-42-demo01/src/test/resources/sql/create_tables.sql
@@ -0,0 +1,5 @@
+CREATE TABLE `t_user` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
+ `username` VARCHAR(64) NOT NULL COMMENT '账号',
+ `password` VARCHAR(64) NOT NULL COMMENT '密码'
+);
diff --git a/lab-42/pom.xml b/lab-42/pom.xml
new file mode 100644
index 00000000..3518bd6b
--- /dev/null
+++ b/lab-42/pom.xml
@@ -0,0 +1,19 @@
+
+
+
+ labs-parent
+ cn.iocoder.springboot.labs
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ lab-42
+ pom
+
+ lab-42-demo01
+
+
+
+
diff --git a/pom.xml b/pom.xml
index ad24b9ab..d3c9bd3e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,7 @@
lab-39
lab-40
lab-41
+ lab-42