【问题标题】:What is the idiomatic way to have a private function tested?测试私有函数的惯用方法是什么?
【发布时间】:2015-10-23 12:41:46
【问题描述】:

Rust 书 says 指出使用“测试”模块是进行单元测试的惯用方式。但是,如果该功能未标记为“pub”,则我无法从测试模块中的超级模块中看到该功能。那么应该如何测试内部功能呢?

我的第一直觉是寻找#ifdef 关键字pub 的方法。我过去曾为 C++ 测试做过这个。对于 Rust,我所做的只是在模块中测试私有函数,然后在“测试”模块中测试公共接口。

我做得对吗?

【问题讨论】:

    标签: unit-testing rust idioms


    【解决方案1】:

    将您的测试模块嵌套在包含私有方法或结构的模块中:

    mod inners {
        fn my_func() -> u8 { 42 }
    
        mod test {
            #[test]
            fn is_answer() {
                assert_eq!(42, super::my_func());
            }
        }
    }
    

    当然,我不同意你应该测试一般的私人东西,但那是不同的讨论。

    【讨论】:

    • 我一开始是这样做的,但我正在做use super::*。如果我只是明确地use super::some_function 它就像你描述的那样工作。谢谢。
    • @SeanPerry AFAIK glob 导入不包括函数,只包括类型。我使用 glob 导入的少数情况之一是在编写测​​试模块时,因为我通常想测试父模块中的所有内容。
    • @Shepmaster 在mod test 上使用#[cfg(test)] 不是一个好习惯吗?
    【解决方案2】:

    测试私有函数的惯用方法是不测试。单元测试应该测试一个类的公共行为。私有方法只是您应该测试的上述公共方法的实现细节。

    【讨论】:

    • 我有简单的内部结构,不记录或打印或任何东西。调用它们的公共程序确实如此。所以我的单元测试是安静的、幂等的等。这不是测试通常隐藏在代码私有区域中的外部访问。
    • @SeanPerry 我不同意经常测试外部访问。事实上,将纯逻辑公开为公共函数或方法允许下游消费者更好。你可以测试你的库的公共接口和用户处理 IO 位。
    • 有时您需要访问实现细节才能通过公共 API 触发特定行为。一个简单的例子是测试数组排序方法:少量,即。大约 10 个元素,使用冒泡排序而不是快速排序(或类似的)通常更快。阈值是一个私有的实现细节,但您需要知道它才能可靠地触发测试中的两个代码路径。
    猜你喜欢
    • 2021-07-21
    • 2012-03-01
    • 2018-05-01
    • 2012-07-18
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    相关资源
    最近更新 更多