Rust 如何在测试中检查std::process::exit()的退出代码?

Rust 如何在测试中检查std::process::exit()的退出代码?,rust,Rust,在锈蚀测试中,是否有一种方法可以检查调用的函数是否真的使用特定的退出代码终止了进程 人为的例子: fn foo(n: i32) { std::process::exit(n); } #[test] fn exits_with_correct_exit_code() { // How do I assert that the following call terminates // the process with exit code 1? foo(1); }

在锈蚀测试中,是否有一种方法可以检查调用的函数是否真的使用特定的退出代码终止了进程

人为的例子:

fn foo(n: i32) {
    std::process::exit(n);
}

#[test]
fn exits_with_correct_exit_code() {
    // How do I assert that the following call terminates
    // the process with exit code 1?
    foo(1);
}
你不能。它的名字很好,但为了以防万一,它所做的某个方面还不清楚:

使用指定的退出代码终止当前进程

此函数将永远不会返回,并将立即终止 当前进程。退出代码被传递到底层操作系统 并可供其他工艺使用

请注意,因为此函数永远不会返回,并且会终止 进程中,当前堆栈或任何其他线程上没有析构函数 堆栈将运行。如果需要清洁停机,建议 仅在已知点调用此函数,该点不再有 任由析构函数运行

运行测试时,每个测试都在单独的线程中运行,但所有测试都在单个进程中运行。当该过程终止时,测试也随之进行

您可以尝试执行一些复杂的递归测试:

#[test]
#[ignore]
fn real() {
    std::process::exit(42)
}

#[test]
fn shim() {
    let status = std::process::Command::new("/proc/self/exe")
        .args(&["--ignored", "real"])
        .status()
        .expect("Unable to run program");

    assert_eq!(Some(42), status.code());
}
这有特定于平台的代码来查找当前流程,但它“起作用”


老实说,我认为代码已经超出了测试范围。您不应该测试
std::process::exit
是否按照它所说的做。如果你真的需要断言一个函数是用一个参数调用的,那就是a的作用

使用依赖项注入提供闭包,捕获闭包中的值,并编写一个薄垫片:

fn foo_logic<F>(n: i32, f: F)
    where F: FnOnce(i32)
{
    f(n);
}

fn foo(n: i32) {
    foo_logic(n, |n| std::process::exit(n));
}

#[test]
fn exits_with_correct_exit_code() {
    let mut value = None;
    foo_logic(1, |v| value = Some(v));
    assert_eq!(Some(1), value);
}
fn foo_逻辑(n:i32,f:f)
式中F:fn一次(i32)
{
f(n);
}
fn-foo(编号:i32){
foo|u逻辑(n,| n | std::process::exit(n));
}
#[测试]
fn使用正确的退出代码()退出{
让mut值=无;
foo|u逻辑(1,| v | value=Some(v));
断言(一些(1),值);
}

你也可以考虑提取计算潜在错误代码并直接测试的逻辑。

< P>你不能。它的名字很好,但为了以防万一,它所做的某个方面还不清楚:

使用指定的退出代码终止当前进程

此函数将永远不会返回,并将立即终止 当前进程。退出代码被传递到底层操作系统 并可供其他工艺使用

请注意,因为此函数永远不会返回,并且会终止 进程中,当前堆栈或任何其他线程上没有析构函数 堆栈将运行。如果需要清洁停机,建议 仅在已知点调用此函数,该点不再有 任由析构函数运行

运行测试时,每个测试都在单独的线程中运行,但所有测试都在单个进程中运行。当该过程终止时,测试也随之进行

您可以尝试执行一些复杂的递归测试:

#[test]
#[ignore]
fn real() {
    std::process::exit(42)
}

#[test]
fn shim() {
    let status = std::process::Command::new("/proc/self/exe")
        .args(&["--ignored", "real"])
        .status()
        .expect("Unable to run program");

    assert_eq!(Some(42), status.code());
}
这有特定于平台的代码来查找当前流程,但它“起作用”


老实说,我认为代码已经超出了测试范围。您不应该测试
std::process::exit
是否按照它所说的做。如果你真的需要断言一个函数是用一个参数调用的,那就是a的作用

使用依赖项注入提供闭包,捕获闭包中的值,并编写一个薄垫片:

fn foo_logic<F>(n: i32, f: F)
    where F: FnOnce(i32)
{
    f(n);
}

fn foo(n: i32) {
    foo_logic(n, |n| std::process::exit(n));
}

#[test]
fn exits_with_correct_exit_code() {
    let mut value = None;
    foo_logic(1, |v| value = Some(v));
    assert_eq!(Some(1), value);
}
fn foo_逻辑(n:i32,f:f)
式中F:fn一次(i32)
{
f(n);
}
fn-foo(编号:i32){
foo|u逻辑(n,| n | std::process::exit(n));
}
#[测试]
fn使用正确的退出代码()退出{
让mut值=无;
foo|u逻辑(1,| v | value=Some(v));
断言(一些(1),值);
}

您也可以考虑提取计算潜在错误代码并直接测试的逻辑。

当然,您必须生成一个过程。但是,我建议这是一个设计不良的接口,并且您应该从实际逻辑中分离副作用(<代码> STD::流程::退出<代码>)。但有时您会被一些输入上存在的第三方函数所困扰。对于恐慌症,至少有
#[应该恐慌]
,但我找不到适用于
std::process::exit()
。当然,您必须生成一个进程。不过,我建议这是一个设计糟糕的界面,您应该分离副作用(
std::process::exit
)从实际逻辑上看。@Veedrac:我完全同意,但有时您会被第三方函数卡住,该函数在某些输入上存在。对于恐慌症,至少有
#[应该恐慌]
,但我找不到适用于
std::process::exit()