似乎不能在Rust doc测试中使用#[tokio-test]
来测试异步功能吗?
现在,我必须编写一个异步主函数,并用#[tokio-main]
对其进行标记,然后在其中调用test_fn().await
,以使某些异步函数在cargo test --doc
期间运行。
是否还有其他更好的方法可以使文档测试像普通测试功能一样运行,例如使用#[tokio-test]
?如果标签#[tokio-test]
可以显示在文档中,那也很好,因此用户可以复制文档并将其直接用作项目中的测试。 (这可能可以像##[tokio-test]
一样完成吗?)
答案 0 :(得分:1)
如果您想在 doctest 中使用异步代码而不为每个生成新的运行时,您可以将整个 doctest 包装起来,而不仅仅是将异步部分包装在 tokio_test::block_on
中。
示例:
/// Asynchronously get length of "aaaa"
/// ```
/// # tokio_test::block_on(async {
/// let len = async { "aaaa".len() };
/// assert_eq!(len.await, 4)
/// # })
/// ```
答案 1 :(得分:0)
文档测试会自动将代码块包装在同步 fn main() { … }
中。 .awaiting
需要异步运行时。如果没有产生某种运行时,就无法.await
。您可以为每个文档测试生成一个运行时:
/// ```rust
/// #[tokio::main]
/// async fn main() {
/// let len = async { "aaaa".len() }.await;
/// assert_eq!(len, 4);
/// }
/// ```
为每个文档测试生成运行时可能不是最好的主意。更好的方法是使用tokio_test::block_on
,它使用测试本地运行时(类似于#[tokio-test])
来阻止提供的将来:
/// ```rust
/// let len = tokio_test::block_on( async { "aaaa".len() } );
/// assert_eq!(len, 4);
/// ```
要减少样板,可以为block_on
设置宏:
macro_rules! bo {
($e:expr) => {
tokio_test::block_on($e)
};
}
并像这样使用它:
/// ```rust
/// let len = async { "aaaa".len() };
/// assert_eq!(bo!(len), 4)
/// ```