如何在Rust中测试struct的实例化?

时间:2014-08-03 23:13:20

标签: unit-testing struct rust

我有以下struct

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 s的结构时会发生什么,指向现有文件和没有现有文件:

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

如何测试struct instantiation?

2 个答案:

答案 0 :(得分:5)

我认为你误解了这些事情的运作模式。

返回类型为Settings的函数 - 它返回时的值是Settings对象,保证正确实例化。如果我们删除了您的assert!(settings);行,代码就会完全符合您的要求。 (assert!期望布尔值作为它的第一个参数,就像if需要一个布尔表达式来跟随它一样。)

如果路径是不存在的路径,则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() })
        }
    }
}

答案 1 :(得分:0)

我认为问题在于这一行

assert!(settings);

断言如果内部的布尔参数为false,则抛出错误但在这种情况下的设置不是布尔值,它的类型为配置::设置

cannot apply unary operator `!` to type `configuration::Settings`

要测试你是否有有效的设置,请执行

之类的操作
assert!(settings.something.is_empty())