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



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

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

有几个关于特质嘲讽的库,但我读到的关于这个主题的书很少,这表明这不是我想要的。

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

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

您可以尝试使用类似mockall的mock-crate,我认为它更完整,但可能还需要一些时间来适应。
如果没有mock-craft,我建议嘲笑其他中的特征/结构,然后使用#[cfg(test)]属性将其纳入范围。当然,这将强制您使用`#[cfg(not(test((]注释productionuse语句。例如:

如果您使用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,否则将使用真正的依赖项。

最新更新