单元测试的正确打开方式:测什么、不测什么

Unit Testing Done Right: What to Test and What Not To

| Lisa | 2026-09-01T08:38:08

团队的测试覆盖率一直上不去,不是因为不想写测试,而是不知道该测什么。这篇文章聊聊我对单元测试范围的理解。

Our test coverage couldn't improve because the team didn't know what to test. Here's my take on defining the right scope for unit tests.

前段时间团队定了个目标:核心模块的测试覆盖率达到 80%。结果大家为了凑覆盖率写了一堆没意义的测试,比如测 getter/setter、测构造函数。覆盖率是上去了,但测试完全没有发现过 bug。 应该测什么 1. 业务逻辑 这是最有价值的测试。比如价格计算、权限判断、状态流转这些: @Test void shouldApplyMemberDiscount() { Order order = new Order(); order.setOriginalPrice(Money.of(100)); order.setUserLevel(UserLevel.VIP); Money finalPrice = priceCalculator.calculate(order); assertEquals(Money.of(80), finalPrice); // VIP 打 8 折 } @Test void shouldNotAllowRefundAfterShipped() { Order order = new Order(); order.setStatus(OrderStatus.SHIPPED); assertThrows(BusinessException.class, () -> orderService.refund(order)); } 2. 边界条件 空值、最大最小值、边界值这些是最容易出 bug 的地方: @Test void shouldHandleEmptyList() { List<Product> result = searchService.search(""); assertTrue(result.isEmpty()); } @Test void shouldHandleMaxPageSize() { PageResult result = newsService.list(1, 10000); // 传了超大的 pageSize assertEquals(100, result.getRecords().size()); // 应该被限制为最大 100 } 3. 异常处理 @Test void shouldThrowWhenDatabaseUnavailable() { when(userMapper.selectById(any())).thenThrow(new DataAccessException("DB down")); assertThrows(ServiceException.class, () -> userService.getUser(1L)); } 不应该测什么 getter/setter:纯数据传递,没有逻辑 框架功能:比如 Spring 的依赖注入能不能正常工作,那是框架的责任 私有方法:通过公开方法间接测试就好,如果私有方法复杂到需要单独测试,说明它应该被提取成一个独立的类 数据库 CRUD:简单的增删改查用集成测试覆盖更合适 好测试的特征 快:毫秒级完成,不依赖外部服务 独立:测试之间不依赖执行顺序 可读:测试方法名就能看出在测什么 一个断言:每个测试只验证一个行为


Team was writing meaningless tests (getter/setter, constructors) to hit coverage targets. Here's what actually deserves testing. Test These Business logic (price calculations, permission checks, state transitions) Boundary conditions (empty lists, max values, edge cases) Exception handling paths Skip These Getter/setter, framework features, private methods (test through public API), simple CRUD (use integration tests). Good Test Traits Fast (milliseconds), independent (no order dependency), readable (method name describes behavior), single assertion.

← Back to News