如何在 Rust 中模拟 std::something?

问题描述 投票:0回答:1

假设我有这个:

fn something(path: String) {
     let contents: Vec<u8> = std::fs::read(path);
     ...
}

如何模拟对

std::fs::read()
的调用?我知道 Rust 不支持开箱即用的模拟,但即使使用像 Mockall 这样的库,我也看不出这是如何做到的。

这些库可以模拟我定义的特征和结构,因为我可以注释它们,但我不明白这应该如何与标准库模块一起使用。

也许mockall不是正确的工具?我应该使用什么库?

rust mocking
1个回答
0
投票

您可以有条件地选择要使用几种不同方式的

read

模拟功能

在此示例中,仅当正在构建测试时,我们才定义自己的

read
,否则我们导入
std::fs::read

use std::path::Path;

#[cfg(not(test))]
use std::fs::read;

#[cfg(test)]
fn read(p: impl AsRef<Path>) -> std::io::Result<Vec<u8>> {
    todo!()
}

fn example() {
    let data = read("path").unwrap();
}

fn main() {
    example();
}

#[cfg(test)]
mod tests {
    #[test]
    fn example() {
        super::example();
    }
}

在调用站点有条件地调用模拟函数

在这种情况下,我们使用

cfg!
宏来决定在调用站点调用哪个函数。优化器将消除另一个分支作为死代码。

use std::path::Path;

fn mock_read(p: impl AsRef<Path>) -> std::io::Result<Vec<u8>> {
    todo!()
}

fn example() {
    let data = if cfg!(test) {
        mock_read("path")
    } else {
        std::fs::read("path")
    }
    .unwrap();
}

fn main() {
    example();
}

#[cfg(test)]
mod tests {
    #[test]
    fn example() {
        super::example();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.