9.5 KiB
9.5 KiB
本次实验的主要任务是完成期末案例的实体类开发和单元测试,并且熟悉IDEA工具的代码自动生成功能。
环境准备
{{< admonition warning >}}
每天的代码要保留一份单独的压缩包,命名示例:day1.rar
{{< /admonition >}}
- 导入JUnit依赖(下方两个包放到lib目录)
- 配置好MySQL数据库(参考Day 1)
junit-4.13.2.jar hamcrest-core-1.3.jar
{{< admonition quote 包说明>}}
- junit-4.13.2.jar 是一个用来测试Java程序的工具
- hamcrest-core-1.3.jar 是JUnit工具的依赖包 {{< /admonition >}}
任务内容
1. 实体类开发
1.1 请假申请实体类(LeaveRequest.java)
package model;
import java.util.Date;
/**
* 请假条实体类
*/
public class LeaveRequest {
private int id; // 数据库主键ID
private Student student; // 学生信息
private Date startTime; // 开始时间
private Date endTime; // 结束时间
private double duration; // 时长
private String location; // 外出地址
private String reasonType; // 外出事由类型
private String reasonDetail; // 详细事由
private boolean isLeavingCity; // 是否离津
private ApprovalStatus status; // 审批状态
private Teacher approver; // 审批人
private String approvalComment; // 审批意见
private Date requestTime; // 申请时间
private Date approvalTime; // 审批时间
// 构造方法
// getter和setter方法
}
操作步骤:
- 在
src/model
目录下创建LeaveRequest.java
文件 - 复制上述代码框架
- 实现默认构造方法,设置初始状态为
PENDING
- 使用IDE自动生成所有属性的
getter
和setter
方法
1.2 审批状态枚举(ApprovalStatus.java)
该文件的代码是完整的,无需修改
package model;
/**
* 请假审批状态枚举类
*/
public enum ApprovalStatus {
PENDING("待审批"), // 等待审批
APPROVED("已批准"), // 已经批准
REJECTED("已驳回"); // 已经驳回
private final String description; // 状态描述
ApprovalStatus(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
enum是枚举类型,用于表示一组固定的常量。
{{< admonition >}}
类似地步骤,完成Teacher
实体类和Student
实体类
{{< /admonition >}}
1.3 教师实体类(Teacher.java)
package model;
/**
* 教师实体类
*/
public class Teacher {
private int id; // 数据库主键ID
private String teacherId; // 教师工号
private String name; // 教师姓名
private String department; // 所属部门
private String contact; // 联系方式
private String password; // 登录密码
// 使用 IDE 自动生成以下内容:
// 构造方法
// getter 和 setter 方法
}
2. 单元测试开发
什么是单元测试?
单元测试是检查程序中最小单位(一个方法、一个功能)是否正确运行的测试。
为什么要做单元测试?
- 及早发现程序中的错误
- 确保修改代码后,原有功能仍然正常
- 节省手工测试的时间
单元测试的优点
- 自动化:写好测试代码后可以反复运行
- 快速:一次能测试多个功能点
- 可靠:比人工测试更准确
在实际开发中,单元测试是保证代码质量的重要手段。以后你们进入公司工作,很可能会遇到需要写单元测试的要求。对Java代码进行单元测试,常用的工具(包)是Junit
{{< admonition success 注意>}} 本次任务需要了解单元测试的意义、方法,后期的单元测试代码会给同学们提供完整代码。 {{< /admonition >}}
2.1 创建测试目录
- 在
src
目录下创建test
目录 - 在
test
目录下创建model
子目录 - 在
test/model
目录下创建各个测试类
2.2 编写Teacher测试类(TeacherTest.java)
package test.model;
import model.Teacher;
import org.junit.Test;
import static org.junit.Assert.*;
public class TeacherTest {
@Test
public void testConstructorAndGetters() {
String teacherId = "T001";
String name = "张老师";
String department = "计算机系";
String contact = "13800138000";
String password = "password123";
Teacher teacher = new Teacher(teacherId, name, department, contact, password);
assertEquals("教师工号应匹配", teacherId, teacher.getTeacherId());
assertEquals("教师姓名应匹配", name, teacher.getName());
assertEquals("所属部门应匹配", department, teacher.getDepartment());
assertEquals("联系方式应匹配", contact, teacher.getContact());
assertEquals("密码应匹配", password, teacher.getPassword());
}
@Test
public void testSetters() {
Teacher teacher = new Teacher();
int id = 1;
String teacherId = "T002";
String name = "李老师";
String department = "数学系";
String contact = "13900139000";
String password = "newpass123";
teacher.setId(id);
teacher.setTeacherId(teacherId);
teacher.setName(name);
teacher.setDepartment(department);
teacher.setContact(contact);
teacher.setPassword(password);
assertEquals("ID应匹配", id, teacher.getId());
assertEquals("教师工号应匹配", teacherId, teacher.getTeacherId());
assertEquals("教师姓名应匹配", name, teacher.getName());
assertEquals("所属部门应匹配", department, teacher.getDepartment());
assertEquals("联系方式应匹配", contact, teacher.getContact());
assertEquals("密码应匹配", password, teacher.getPassword());
}
}
操作步骤:
- 创建TeacherTest.java文件
- 编写构造方法测试用例
- 编写getter/setter方法测试用例
2.4 编写DatabaseUtil测试类(DatabaseUtilTest.java)
package test.util;
import org.junit.Test;
import util.DatabaseUtil;
import java.sql.Connection;
import java.sql.SQLException;
import static org.junit.Assert.*;
public class DatabaseUtilTest {
@Test
public void testGetConnection() {
try (Connection conn = DatabaseUtil.getConnection()) {
// 验证连接不为空
assertNotNull("数据库连接不应该为空", conn);
// 验证连接是否有效
assertTrue("数据库连接应该是有效的", !conn.isClosed());
} catch (SQLException e) {
fail("获取数据库连接时发生异常: " + e.getMessage());
}
}
@Test
public void testConnectionAutoClose() {
Connection conn = null;
try {
// 在try-with-resources块中获取连接
try (Connection autoCloseConn = DatabaseUtil.getConnection()) {
assertNotNull("数据库连接不应该为空", autoCloseConn);
assertTrue("连接应该是开启状态", !autoCloseConn.isClosed());
}
// try-with-resources块结束后,获取一个新连接来测试
conn = DatabaseUtil.getConnection();
assertNotNull("新的数据库连接不应该为空", conn);
assertTrue("新的连接应该是开启状态", !conn.isClosed());
} catch (SQLException e) {
fail("测试连接自动关闭时发生异常: " + e.getMessage());
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
操作步骤:
- 在test.util包下创建DatabaseUtilTest.java文件
- 编写测试数据库连接的方法testGetConnection()
- 编写测试连接自动关闭的方法testConnectionAutoClose()
- 确保使用try-with-resources语句来自动管理数据库连接资源
完成标准
- 所有实体类完整实现
- Teacher类(属性、构造方法、getter/setter)
- Student类(属性、构造方法、getter/setter)
- LeaveRequest类(属性、构造方法、getter/setter)
- ApprovalStatus枚举(所有状态值和描述)
- 所有单元测试通过
- TeacherTest全部测试用例通过
- DatabaseUtilTest全部测试用例通过
- 代码规范
- 适当的注释说明
- 规范的命名
- 合理的代码组织
编码规范
- 类名使用大驼峰命名法(如:
TeacherTest
) - 方法名使用小驼峰命名法(如:
testConstructor
) - 变量名使用小驼峰命名法(如:
teacherId
) - 常量使用全大写(如:
PENDING
) - 每个类都要有类注释
- 重要方法要有方法注释
测试运行方法
- 在IDE中右键点击test包
- 选择"Run 'Tests in test'" 运行所有测试类
- 或右键点击test内的某个包,选择"Run 'Tests in 包名'"运行包内所有测试
- 或右键点击单个测试类,选择"Run 'Tests in 类名'"运行单个测试类
- 查看测试结果:绿色√表示通过,红色×表示失败
提示与建议
- 使用IDE的代码生成功能可以快速生成getter/setter方法
- 测试用例要考虑各种可能的情况
- 测试失败时要仔细阅读错误信息
- 定期运行所有测试,确保修改不会影响其他功能