具有异步功能#[tokio-test]

时间:2020-10-28 07:41:41

标签: rust rust-cargo rust-tokio

似乎不能在Rust doc测试中使用#[tokio-test]来测试异步功能吗?

现在,我必须编写一个异步主函数,并用#[tokio-main]对其进行标记,然后在其中调用test_fn().await,以使某些异步函数在cargo test --doc期间运行。

是否还有其他更好的方法可以使文档测试像普通测试功能一样运行,例如使用#[tokio-test]?如果标签#[tokio-test]可以显示在文档中,那也很好,因此用户可以复制文档并将其直接用作项目中的测试。 (这可能可以像##[tokio-test]一样完成吗?)

2 个答案:

答案 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)
/// ```