如何在 Rust 测试中为所有测试函数创建一个具有范围/生命周期的变量? [英] How to make a variable with a scope/lifecycle for all test functions in a Rust test?

查看:32
本文介绍了如何在 Rust 测试中为所有测试函数创建一个具有范围/生命周期的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

#[测试]fn test_one() {让 root = Path::new("data/");//剩下的测试}#[测试]fn test_two() {让 root = Path::new("data/");//剩下的测试}

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

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

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

解决方案

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

<块引用>

并且不要重复初始化代码

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

使用 std::path::PathBuf;fn root() ->路径缓冲{PathBuf::from("数据/")}#[测试]fn test_one() {让 root = root();//剩下的测试}#[测试]fn test_two() {让 root = root();//剩下的测试}

<块引用>

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

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

使用 std::path::{Path, PathBuf};结构设置{根:PathBuf,}实现设置{fn new() ->自己 {自己 {root: PathBuf::from("data/"),}}}#[测试]fn test_one() {让 setup = Setup::new();让根:&Path = &setup.root;//剩下的测试}#[测试]fn test_two() {让 setup = Setup::new();让根:&Path = &setup.root;//剩下的测试}

<块引用>

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

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

#[macro_use]extern crate lazy_static;使用 std::path::Path;懒惰的静态!{static ref ROOT: &'static Path = Path::new("data/");}#[测试]fn test_one() {让 root = *ROOT;//剩下的测试}#[测试]fn test_two() {让 root = *ROOT;//剩下的测试}

另见:

<小时>

非常适合您的情况,您需要一个 Path 的情况非常少见,因为字符串切片实现了 AsRef.换句话说,大多数接受 Path 的地方都接受 &str:

static ROOT: &str = "data/";#[测试]fn test_one() {让 root = ROOT;//剩下的测试}#[测试]fn test_two() {让 root = ROOT;//剩下的测试}

I have a test that initializes a variable before diving into the detail of the test, and I want to make a second test with the same variable, and not duplicate the initialization code:

#[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
}

I don't think static or const would do it because the size would not be known up front, though PathBuf.from(path) might make that OK, except that initialization expressions for static/const vars cannot be too complex.

I've seen lazy_static, but have not seen any examples of its use in tests. This after seeing the compiler error with "an extern crate loading macros must be at the crate root", which online searching tells me is something about being outside main(), but tests don't have main functions.

In Java, I would define the variable then initialize it in a setup() method, but I can't see examples of that online for Rust.

解决方案

Foremost, remember that Rust tests are run in parallel. This means that any shared setup needs to be thread-safe.

and not duplicate the initialization code

You do it the same way you avoid duplicating any other code: create a function, create a type, create traits, etc.:

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
}

In Java I would define the variable, then initialize it in a setup() method

Instead, make a struct called Setup containing all those variables and construct it as the first thing in each test:

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
}

but have not seen any examples of [lazy-static] use in tests

That's because there is no different way to use it in tests, it's just code:

#[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
}

See also:


Very specifically for your case, it's very rare that you need exactly a Path, since a string slice implements AsRef<Path>. Said another way, most places that accept a Path accept 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
}

这篇关于如何在 Rust 测试中为所有测试函数创建一个具有范围/生命周期的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆