第 09 章 第 09 章 单元测试与可测试性:敢改别人的代码(已拆分为多篇)
原章约 87375 字符,较长。已按主题拆分为以下小节,单篇约 15 分钟可读。
本节导航
原章开头引子
你现在是那个订单服务的 owner。3 万行代码,0 个测试。 leader 走过来说:「加个功能,订单支持优惠券。」 你知道该改哪里 ——
OrderServiceImpl.createOrder()第 147 行往下,加一段算价。但你不敢改,因为你没有任何办法验证改完之后别的地方会不会炸。 于是你打开这个项目里唯一存在的OrderServiceImplTest.java,看到的是这个:
@SpringBootTest // 启动完整 Spring 容器
public class OrderServiceImplTest {
@Autowired
private OrderService orderService; // 真 Bean,连真 MySQL
@Test
public void testCreateOrder() {
// ...一堆断言
}
}跑一次 47 秒。47 秒里大概有 8 秒是 JVM 启动、20 秒是 Spring 容器装配和 classpath 扫描、剩下的是连数据库和 IO 等待。
问题 1(先想三十秒): 3 万行代码,你打算写多少个这样的测试?全量跑一遍要多久?跑不完的测试,跟没有测试的区别是什么?
这道题的答案不是”多写点测试”或者”优化一下”。它逼你承认一件事:测试的瓶颈从来不是”会不会写”,而是”代码允不允许你写”。 那个 47 秒的测试之所以要启动整个容器、连真实数据库,不是因为写它的人懒,而是因为 OrderServiceImpl 里的依赖是写死的 —— 你没法只测它一个类。
所以这一章不讲”怎么写测试”。讲怎么让代码变得可以被测试,以及拿到一堆测不了的代码时,怎么用最小成本撬开一条缝。