You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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具备完全相同接口的模拟桩实现。

已尝试方案及现存问题

  • 方案一:自定义CANInterface trait,为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:57:12