数码常识网
霓虹主题四 · 更硬核的阅读氛围

依赖注入与单元测试:让代码更易测试的实用技巧

发布时间:2025-12-21 18:50:20 阅读:200 次

依赖注入与单元测试:让代码更易测试的实用技巧

写代码时,你有没有遇到过这种情况:想给某个类写个单元测试,结果发现它直接创建了数据库连接、调用了外部API,甚至还读取了配置文件。一跑测试,要么超时,要么得先把整个环境搭好,烦不胜烦?

这时候,依赖注入(Dependency Injection,简称DI)就能派上用场了。它不只是框架里的高级概念,更是写可测试代码的关键。

为什么依赖注入能帮到单元测试?

想象一下你在做一道菜,需要酱油。如果这道菜的做法是“自己去超市买酱油”,那你每次想试味道都得出门一趟。但如果改成“别人把酱油递给你”,你就可以在厨房里直接换不同牌子的酱油来尝——这就是依赖注入的核心思想。

在代码中,一个类不该自己去“创建”它所依赖的对象,而是应该通过构造函数或方法参数“接收”这些依赖。这样一来,写单元测试的时候,你就可以传入一个“假”的依赖(也就是Mock),而不是真实的、难以控制的服务。

一个简单的例子

比如我们有个订单服务,需要发送邮件通知:

class OrderService {
private EmailService emailService;

public OrderService() {
this.emailService = new EmailService(); // 直接new,问题就在这
}

public void placeOrder(String user) {
// 处理订单逻辑
emailService.send(user, "订单已创建");
}
}

这个写法在测试时会真的发邮件,显然不合适。改用依赖注入后:

class OrderService {
private EmailService emailService;

public OrderService(EmailService emailService) {
this.emailService = emailService; // 由外部传入
}

public void placeOrder(String user) {
// 处理订单逻辑
emailService.send(user, "订单已创建");
}
}

现在写测试就轻松多了:

[Test]
public void should_send_email_when_order_placed() {
EmailService mockEmailService = Mockito.mock(EmailService.class);
OrderService service = new OrderService(mockEmailService);

service.placeOrder("alice");

verify(mockEmailService).send("alice", "订单已创建");
}

你看,根本不需要真正的邮件服务,也能验证逻辑是否正确。

实际开发中的常见做法

很多项目用Spring这类框架管理依赖注入,但即使不用框架,手动传递依赖也是完全可行的。关键在于设计时要有意识:别让类自己去“找”依赖,而是让它“等着被给”。

当你写出这样的代码,单元测试自然就变得简单、快速、稳定。测试不再依赖网络、数据库或第三方服务,可以在本地秒级运行,这对持续集成和日常调试都有巨大帮助。

归根结底,依赖注入不是为了炫技,而是为了让代码更容易被验证。而单元测试,正是验证代码是否靠谱的第一道防线。