在 java 中对 void 方法进行单元测试断言,主要通过以下三种策略实现(以 junit 和 assertj 为例):
1. 验证状态变化(最常用)
测试方法执行后对象或系统状态的改变:
@test
void reset_shouldclearcounter() {
counter counter = new counter();
counter.increment(); // 初始值+1
// 执行 void 方法
counter.reset();
// 验证内部状态
assertequals(0, counter.getcount());
// 使用 assertj 更优雅的断言
assertthat(counter.getcount()).iszero();
}2. 验证行为交互(使用 mockito)
当 void 方法依赖其他对象时,验证是否正确调用协作对象:
@test
void notifyuser_shouldtriggernotificationservice() {
// 创建依赖项的 mock
notificationservice mockservice = mock(notificationservice.class);
userservice userservice = new userservice(mockservice);
// 执行 void 方法
userservice.notifyuser("user123");
// 验证是否调用了依赖对象的特定方法
verify(mockservice).sendnotification(eq("user123"));
// 验证调用次数
verify(mockservice, times(1)).sendnotification(any());
}3. 验证异常抛出
测试方法在非法输入时的异常行为:
@test
void withdraw_shouldthrowexceptionwhenoverdraft() {
account account = new account(100);
// 验证异常断言 (junit 5)
assertthrows(insufficientfundsexception.class, () -> {
account.withdraw(200); // void 方法
});
// assertj 异常断言
assertthatthrownby(() -> account.withdraw(200))
.isinstanceof(insufficientfundsexception.class)
.hasmessage("余额不足");
}最佳实践建议:
状态优先原则:优先验证对象状态变化而非内部行为
行为验证场景:
- 当调用外部系统接口(如发送邮件)
- 需要确认调用顺序或次数(如多次调用)
自定义验证器:复杂状态可封装验证逻辑
@test
void updateprofile_shouldchangemultiplefields() {
user user = new user();
user.updateprofile("alice", 30, "alice@email.com");
// 自定义断言方法
assertuserprofile(user, "alice", 30, "alice@email.com");
}
private void assertuserprofile(user user, string name, int age, string email) {
assertthat(user.getname()).isequalto(name);
assertthat(user.getage()).isequalto(age);
assertthat(user.getemail()).isequalto(email);
}完整测试示例:
public class shoppingcarttest {
@test
void clear_shouldremoveallitems() {
// 准备
shoppingcart cart = new shoppingcart();
cart.additem(new item("book", 15.99));
cart.additem(new item("pen", 1.99));
// 执行
cart.clear();
// 验证
assertthat(cart.isempty())
.as("购物车应在清空后为空")
.istrue();
}
@test
void processorder_shouldpersisttodatabase() {
// 准备
orderdao mockdao = mock(orderdao.class);
orderservice service = new orderservice(mockdao);
order order = new order("order-123");
// 执行
service.processorder(order);
// 验证数据库交互
verify(mockdao).save(order);
}
@test
void setdiscount_shouldthrowforinvalidvalue() {
product product = new product();
assertthatthrownby(() -> product.setdiscount(-10))
.isinstanceof(illegalargumentexception.class)
.hasmessagecontaining("折扣值非法");
}
}关键结论:
- void 方法通过间接验证状态变化或检查方法行为进行断言
- 优先使用 assertequals/assertthat 检查状态变化
- 对依赖交互使用 mockito 的 verify
- 异常场景用 assertthrows/assertthatthrownby
- 复杂断言使用自定义断言方法保持可读性
对于现代 java 测试,推荐使用 assertj 提供的丰富断言(如 assertthat().isempty())和 mockito 进行行为验证,比传统的 junit 断言更具表达力。
到此这篇关于java void方法单测断言的三种实现示例的文章就介绍到这了,更多相关java void断言内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论