JUnit测试在代码存在人为植入错误时仍全部通过的问题排查
JUnit sell方法测试恒通过问题排查
你的测试无论业务代码是否出错都能通过,核心原因是你从始至终都没有调用被测的sell方法,整个测试逻辑是你在测试方法里重写了一遍自己理解的业务流程,完全没有校验实际业务方法的执行结果,本质是在"自导自演",自然永远不会失败。
具体问题点
- 未调用被测业务方法
整个reStock测试方法中没有任何一行调用sell(myUser, item)的代码。所有角色校验、库存遍历、商品匹配、余额判断的逻辑都是你在测试代码里手写复刻的,和你业务类中实现的sell方法完全无关。哪怕你把sell方法的代码全部删掉改成空实现,测试依然会按照你自己写的分支逻辑执行,不会检测到任何问题。 - 断言全部是无意义的自校验
你写的所有断言都是对自己测试代码中刚生成的判断结果做校验,永远不会失败:- 你先通过
if(myUser.getRole() == Roles.CASHIER)进入分支,再断言myUser.getRole() == Roles.CASHIER,属于恒真判断 - 你自己在测试代码里执行
inventories.remove(inventory),再断言集合长度变化,本质是在测试JDK中ArrayList的remove功能,和你的业务逻辑没有任何关系 - 所有错误分支(非收银员角色、商品不匹配、余额不足)里只有打印语句,没有任何失败断言,哪怕走到错误场景,测试也只会打一行日志就正常标记为通过
- 你先通过
- 缺少明确的测试前置初始化
测试依赖的myUser、inventories、item等成员变量没有固定的初始化逻辑,状态完全不确定,很容易出现所有断言分支都没走到,测试空跑通过的情况。
正确测试写法参考
写JUnit测试的固定流程是:初始化测试场景 -> 调用被测方法 -> 断言方法执行后的实际结果符合预期,不要在测试里重写业务逻辑。
// 每个测试执行前先构造固定的测试数据,避免状态干扰 @BeforeEach void setUp() { inventories = new ArrayList<>(); // 往库存里加一个售价100的商品apple inventories.add(new Product("apple", 100)); // 构造余额200的收银员用户 myUser = new User(Roles.CASHIER, 200); } @Test void sell_shouldRemoveItem_whenCashierHasEnoughBalance() { int sizeBeforeSell = inventories.size(); // 核心:调用被测的sell方法 sell(myUser, "apple"); // 断言执行结果符合预期 Assertions.assertEquals(sizeBeforeSell - 1, inventories.size()); boolean appleStillInStock = inventories.stream() .anyMatch(p -> "apple".equals(p.getName())); Assertions.assertFalse(appleStillInStock); } @Test void sell_shouldKeepStock_whenUserIsNotCashier() { User normalStaff = new User(Roles.STAFF, 200); int sizeBeforeSell = inventories.size(); sell(normalStaff, "apple"); // 非收银员购买,库存不应该变化 Assertions.assertEquals(sizeBeforeSell, inventories.size()); } @Test void sell_shouldKeepStock_whenCashierBalanceNotEnough() { User poorCashier = new User(Roles.CASHIER, 50); int sizeBeforeSell = inventories.size(); sell(poorCashier, "apple"); // 余额不足,库存不应该变化 Assertions.assertEquals(sizeBeforeSell, inventories.size()); }
补充说明:你当前实现的sell方法本身也存在逻辑问题,比如遍历ArrayList时直接调用remove会抛出ConcurrentModificationException,再比如遍历库存时只要遇到不匹配的商品就打印"缺货",哪怕库存中实际存在目标商品。等你把测试逻辑写正确之后,这些问题都会在跑测试时被自动检测出来。
内容的提问来源于stack exchange,提问作者Ifeoluwa Clement
相关产品推荐
相关产品推荐

