调用被测试模块中的私有函数

在某些情况下,开发者可能希望测试私有函数或使用私有函数创建私有数据结构。你可以通过将这些私有函数设置为 public(package), 并在被测试模块中将测试模块声明为 package 来实现。然而,赋予函数比必要更高的可见性并不是一个好习惯。相反,你可以使用 #[test_only] 属性来允许函数仅从测试模块调用。这个属性仅在测试模块中可用,而在生产代码中不可用。

module my_package::my_module {
    fun private_function() {
        // ...
    }
    
    #[test_only]
    fun call_private_function() {
        private_function();
    }
}

module my_package::my_module_tests {
    use my_package::my_module;
    
    #[test]
    fun test_private_function() {
        my_module::call_private_function();
        // ...
    }
}

编写测试时需要记住的几点:

  • #[test_only] 函数对于调用被测试模块的 init 函数特别有用,因为在运行测试时 init 函数默认不会被调用。必须显式调用它们。
  • 确保不要拼错 #[test_only],例如拼成 #[testonly] 或 #[test_onlyy],因为这会使函数变为非测试函数!如果测试代码被部署,
  • 例如一个铸币函数,这可能会是灾难性的。虽然编译器现在可以捕捉到这个错误,但确保注释正确仍然是一个好的实践。
  • 如果没有必要,开发者不应该滥用 #[test_only] 函数。
  • 如果在被测试模块中有仅在测试函数中使用的导入,可以在导入上使用 #[test_only] 注释。否则,编译器可能会警告有未使用的导入。