Rust单元测试中外部crate打桩方法及替代实现方案
Rust CANProxy结构体测试的硬件依赖隔离问题
测试自定义结构体时遇到测试依赖隔离问题,待测试的原始结构体定义如下:
struct CANProxy { socket: CANSocket // 其他字段 ....... } impl CANProxy { pub fn new(can_device: &str) -> Self { let socket = CANSocket::open(can_device).unwrap(); // 其他初始化逻辑 ....... Self { socket } } }
测试目标
验证符合规范的消息可通过socket正常传输,但运行测试用例时不实际初始化真实CAN硬件设备,需要构造与cansocket crate提供的CANSocket具备完全相同接口的模拟桩实现。
已尝试方案及现存问题
- 方案一:自定义
CANInterfacetrait,为socketcan::CANSocket实现该trait,再通过泛型绑定让CANProxy支持不同的接口实现。该方案的核心问题是需要重复封装CANSocket的全部对外接口,冗余繁琐、重复工作量极大。 - 方案二:调研过mockall crate,但不确定它是否适用于当前场景,希望找到更优雅的实现方式达成无硬件依赖的测试目标。
此前尝试编写的实现代码如下:
trait CANInterface { fn open(name: &str) -> Result<Self, SomeError>; // ... 此处需要罗列socketcan::CANSocket的全部对外方法 // 重复代码量极大 } ///////////// Proxy 业务代码 struct<T: CANInterface> CANProxy<T> { socket: T // 其他字段 ....... } impl<T: CANInterface> CANProxy<T> { pub fn open(can_device: &str) -> Result<Self, SomeError> { let socket = T::open(can_device).unwrap(); // 其他初始化逻辑 ....... Ok(Self { socket }) } } ////////////// 模拟桩实现 struct FakeCANSocket; impl CANInterface for FakeCANSocket { // ..... 在此处实现模拟桩的对应逻辑 } // 为原生CANSocket实现自定义trait impl CANInterface for socketcan::CANSocket { // 这部分重复代码没有实际业务价值,仅做原生方法的透传调用 fn open(can_device: &str) -> Self { CANSocket::open(can_device) } /// .............. /// .............. /// .............. }
内容的提问来源于stack exchange,提问作者Kalin Kochnev
相关产品推荐
相关产品推荐

