首页 > 解决方案 > 如何编写函数存根来测试 Rust 模块?

问题描述

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

我在 Rust 中搜索了高低的方法来测试被测模块外部的存根函数,但找不到解决方案。

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

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

这似乎非常基本。肯定有办法用 Rust 和 Cargo 存根外部函数吗?

标签: unit-testingrustintegration-testingstub

解决方案


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

如果您使用带有方法的外部结构ExternalStruct,您将拥有如下内容:external-crateexternal_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,否则将使用真正的依赖项。


推荐阅读