如何在 Rust 测试中为所有测试函数创建一个具有范围/生命周期的变量?

pau*_*l_h 5 unit-testing rust

我有一个在深入测试细节之前初始化变量的测试,我想用相同的变量进行第二次测试,而不是重复初始化代码:

#[test]
fn test_one() {
    let root = Path::new("data/");
    // the rest of the test
}
#[test]
fn test_two() {
    let root = Path::new("data/");
    // the rest of the test
}
Run Code Online (Sandbox Code Playgroud)

我不认为staticconst不会这样做,因为大小不会预先知道,尽管PathBuf.from(path)可能会这样做,但静态/常量变量的初始化表达式不能太复杂。

我见过lazy_static,但还没有看到它在测试中使用的任何例子。这是在看到带有“extern crate loading macros must be at the crate root”的编译器错误之后,在线搜索告诉我是在外面main(),但测试没有main功能。

在 Java 中,我会定义变量然后在setup()方法中初始化它,但我看不到 Rust 的在线示例。

She*_*ter 8

首先,请记住 Rust 测试是并行运行的。这意味着任何共享设置都需要是线程安全的。

并且不要重复初始化代码

您这样做的方式与避免复制任何其他代码的方式相同:创建函数、创建类型、创建特征等:

use std::path::PathBuf;

fn root() -> PathBuf {
    PathBuf::from("data/")
}

#[test]
fn test_one() {
    let root = root();
    // the rest of the test
}

#[test]
fn test_two() {
    let root = root();
    // the rest of the test
}
Run Code Online (Sandbox Code Playgroud)

在 Java 中,我会定义变量,然后在一个setup()方法中初始化它

相反,创建一个Setup包含所有这些变量的结构,并将其构造为每个测试中的第一件事:

use std::path::{Path, PathBuf};

struct Setup {
    root: PathBuf,
}

impl Setup {
    fn new() -> Self {
        Self {
            root: PathBuf::from("data/"),
        }
    }
}

#[test]
fn test_one() {
    let setup = Setup::new();
    let root: &Path = &setup.root;
    // the rest of the test
}

#[test]
fn test_two() {
    let setup = Setup::new();
    let root: &Path = &setup.root;
    // the rest of the test
}
Run Code Online (Sandbox Code Playgroud)

但还没有看到任何在测试中使用 [lazy-static] 的例子

那是因为在测试中使用它没有不同的方法,它只是代码:

#[macro_use]
extern crate lazy_static;

use std::path::Path;

lazy_static! {
    static ref ROOT: &'static Path = Path::new("data/");
}

#[test]
fn test_one() {
    let root = *ROOT;
    // the rest of the test
}

#[test]
fn test_two() {
    let root = *ROOT;
    // the rest of the test
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:


非常适合您的情况,您很少需要恰好 a Path,因为字符串切片实现了AsRef<Path>. 换句话说,大多数接受 a 的地方都Path接受 a &str

static ROOT: &str = "data/";

#[test]
fn test_one() {
    let root = ROOT;
    // the rest of the test
}

#[test]
fn test_two() {
    let root = ROOT;
    // the rest of the test
}
Run Code Online (Sandbox Code Playgroud)