如何编写用于测试 Rust 模块的函数存根?

How does one write function stubs for testing Rust modules?

根据我过去测试 C 代码的经验,函数存根几乎是强制性的。在我的安全关键工作中,我通常需要测试所有内容——甚至是抽象函数,它们只是为参数调用特定于构建的实现参数,return for return.

我四处寻找在 Rust 中将被测模块外部的存根函数存根的方法,但找不到解决方案。

有几个用于 trait-mocking 的库,但我对这个主题的了解很少表明它不是我要找的。

另一个建议是,我测试的调用外部函数的函数已经传入了这些函数,允许测试简单地传递所需的伪存根函数。就传入和传出伪存根的数据而言,这似乎非常不灵活,并导致一个人的代码在每一层都被函数引用参数污染——当被测函数除了一个操作函数或存根。您正在编写操作代码以适应测试系统的限制。

这看起来非常基础。肯定有办法用 Rust 和 Cargo 存根外部函数吗?

您可以尝试使用像 mockall 这样的模拟板条箱,我认为它更完整,但可能仍需要一些时间来适应。
如果没有 mock crate,我建议在另一个中模拟 traits/structs,然后使用 #[cfg(test)] 属性将 then 引入范围。当然,这将强制要求您使用 `#[cfg(not(test))] 注释 production use 语句。例如:

如果你使用来自 external-crate 的外部结构 ExternalStruct 和方法 external_method 你会得到类似的东西:

文件real_code.rs

#[cfg(not(test))]
use external-crate::ExternalStruct;
#[cfg(test)]
use test_mocks::ExternalStruct;

fn my_function() {
   //...
   ExternalTrait::external_method();
}

#[test]
fn test_my_function(){
   my_function();
}

文件test_mocks.rs:

pub Struct ExternalStruct {}

impl ExternalStruct {
   pub fn external_method() {
      //desired mock behaviour
   }
}

在 运行 你的测试中,来自 test_mocks 的 ExternalStruct 将被使用,否则将使用真正的依赖。