unit-testing - 如何在 Rust 中测试结构的实例化?

标签 unit-testing struct rust

我有以下结构:

pub struct Settings {
    pub something: String
}

使用以下构造函数:

impl Settings {
    fn new(path: &Path) -> Settings {
        if !path.exists() {
            fail!("Configuration file not found.");
        }
        return Settings{something:String::new()};
    }
}

我已经创建了一个单元测试来查看当我创建一个包含指向现有文件和不存在文件的 Path 结构时会发生什么:

mod tests {
    #[test]
    fn test_new_valid_path() {
        use configuration::Settings;
        let path = &Path::new("emperor.ini");
        let settings = Settings::new(path);
        assert!(settings);
    }

    #[test]
    fn test_new_invalid_path() {
        use configuration::Settings;
        let path = &Path::new("emperor.xml");
        let settings = Settings::new(path);
    }
}

但是当我这样运行测试时:rustc --test meh.rs; ./meh --nocapture 我得到以下输出:

<std macros>:3:12: 40:20 error: cannot apply unary operator `!` to type `configuration::Settings`
<std macros>:3         if !$cond {
<std macros>:4             fail!("assertion failed: {:s}", stringify!($cond))
<std macros>:5         }
<std macros>:6     );
<std macros>:7     ($cond:expr, $($arg:expr),+) => (
<std macros>:8         if !$cond {
               ...
<std macros>:1:1: 12:2 note: in expansion of assert!
shogun.rs:40:4: 40:22 note: expansion site
error: aborting due to previous error

如何测试结构实例化?

最佳答案

我认为您误解了这些东西如何工作的模型。

返回类型为 Settings 的函数——好吧,它返回时的值是 Settings保证被正确实例化的对象。如果我们删除了您的 assert!(settings);行,代码将完全按照您的要求执行。 (顺便说一下,assert! 需要一个 bool 值作为它的第一个参数,就像 if 需要一个 bool 表达式一样。)

如果路径不存在,则fail!将发挥作用,任务将失败,展开; Settings::new电话永远不会回来。触发任务失败到底是什么assert!(…)也是。

换句话说:执行该行的事实证明它已正确初始化。


顺便说一句,这样的失败通常被认为是糟糕的形式;更好的办法是返回 Option<Settings> , 而不是使用名称 new而是表明您将从文件中加载它的东西;像这样:

impl Settings {
    fn load(path: &Path) -> Option<Settings> {
        if !path.exists() {
            None
        } else {
            Some(Settings { something: String::new() })
        }
    }
}

关于unit-testing - 如何在 Rust 中测试结构的实例化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25109962/

相关文章:

c# - 在 Effort 数据库上创建存储过程以进行单元测试

c - 在嵌入式寄存器结构中用位移位替换位域

c++ - C++ 如何用 void 调用 ifstream?

c - 结构体中指针的 Malloc + 指针算术 + free() + linkedList

macros - 如何匹配宏中的方法?

mysql - 返回引用的生命周期不够长

generics - 有没有一种简单的方法可以在 Rust 中使用整型泛型类型?

unit-testing - PHPUnit - 如何在另一个类的方法中模拟该类?

ruby - 如何在摩卡中断言模拟 block

java - Mockito 没有正确 stub 将列表作为参数的方法