依赖注入模式在单元测试中替换后台请求模块
作者:技术拾光时间:2026-06-28 08:19:00浏览:423
依赖注入的本质非常简单:让代码不再自己“new”对象,而是由外部将依赖传递进来。尤其在测试场景中,当需要替换网络请求模块时,这种设计能显著提升效率——无需连接真实服务器,测试运行更快更稳定,且每次结果一致。 简而言之,被测代码不自行创建网络请求对象,而是由外部传入“能发送请求的模块”——测试时将其替
依赖注入的本质非常简单:让代码不再自己“new”对象,而是由外部将依赖传递进来。尤其在测试场景中,当需要替换网络请求模块时,这种设计能显著提升效率——无需连接真实服务器,测试运行更快更稳定,且每次结果一致。

简而言之,被测代码不自行创建网络请求对象,而是由外部传入“能发送请求的模块”——测试时将其替换为可控的伪造版本即可。
将请求逻辑抽象为可替换的接口
切忌在业务类内部直接 new Retrofit 或 URLSession。应先定义一个协议或接口,例如:
- iOS(Swift):声明
protocol NetworkService { func fetchData(completion: @escaping (Result) -> Void) } - Android(Kotlin):定义
interface ApiService { suspend fun getUser(id: Long): User } - C# / Ja va:使用
IHttpService或ApiRepository这类抽象类型,不写入具体实现
业务类仅依赖该接口,不关心其具体实现——这是实现解耦的第一步。
通过构造函数注入,切断硬编码依赖
将网络服务作为参数传入类内部,而非在内部创建:
- 例如
class UserManager(private val api: NetworkService) - 测试时直接传入伪造对象:
UserManager(mockNetworkService) - 真实运行时才传入
RetrofitNetworkService()或AlamofireService()
这种方式无需修改业务代码以添加 setter,也无需改动静态方法,简洁且符合单一职责原则。
测试中使用 Mock 或 Stub 替换真实请求
不调用真实服务器,而是控制返回的数据和行为:
- 使用 Mockito(Ja va/Kotlin) 或 NSubstitute(C#) 创建接口的模拟实例
- 利用 Swift 的协议扩展 + 空实现 编写轻量级 Stub,例如返回固定 JSON 或抛出特定错误
- 验证关键行为:检查
api.fetchData()的调用次数或传入参数是否正确
这类测试快速、稳定且可重复,不惧网络波动,也不依赖后端是否就绪。
框架辅助(可选但推荐)
若项目已使用 DI 容器(如 Dagger、SimpleInjector、Objection、Spring Boot 的 @MockBean),可借助它统一管理替换逻辑:
- 在测试配置中注册 mock 实例,覆盖默认的网络 service Bean
- 避免每个测试手动构造完整依赖链
- 保持测试环境与运行环境结构一致,降低遗漏风险
即使不使用框架也完全可行——只要坚持接口抽象加构造注入,替换仅需几行 new 和参数传递,毫无门槛。
