如何在mod tests中导入带#[op]属性的Rust函数?
问题
我在测试一个用#[op](deno_ops的proc macro)标记的异步函数时遇到了报错。
原函数代码:
#[op] #[instrument(name = "op_xyz", skip_all, ret)] async fn xyz() -> Result<U256, deno_core::error::AnyError> {...}
把测试写在tests子模块里时,代码如下:
#[cfg(test)] mod tests { use super::op_xyz; #[tokio::test] async fn test_op_get_latest_nonce() { let res = op_xyz().await; ... } }
得到错误:
expected function, found `op_xyz`
VS Code的Rust插件提示:
Auto-generated by deno_ops, i.e: #[op] Use op_get_latest_nonce::decl() to get an op-declaration you can include in a deno_core::Extension
注:把测试函数放在tests模块外面就能正常运行,写法如下:
#[op] #[instrument(name = "op_xyz", skip_all, ret)] async fn xyz() -> Result<U256, deno_core::error::AnyError> {...} #[tokio::test] async fn test_op_xyz() { let res = op_xyz().await; ... }
执行cargo test test_op_xyz -- --nocapture能得到正确结果。
原因
#[op]宏会做两件事:
- 在当前模块生成一个和原函数
xyz逻辑一致的op_xyz包装函数,这也是外部测试能直接调用op_xyz()的原因; - 同时生成一个同名的
op_xyz模块,用来给deno_core注册扩展(就是插件提示里说的带decl()方法的模块)。
当你在子模块里用use super::op_xyz时,Rust会优先把它解析成那个模块,而不是包装函数,所以才会报“期望函数,却找到op_xyz(模块)”的错误。
解决方法
有两种简单的解决方式:
方法一:直接测试原函数xyz
既然op_xyz只是原函数的包装,直接测xyz反而更聚焦业务逻辑:
#[cfg(test)] mod tests { use super::xyz; // 改成导入原函数 #[tokio::test] async fn test_op_get_latest_nonce() { let res = xyz().await; ... } }
方法二:明确调用包装函数
如果非要测宏生成的包装层,可以用完整路径调用,或者给函数起别名避免混淆:
#[cfg(test)] mod tests { // 方式1:用别名区分模块和函数 use super::op_xyz as op_xyz_fn; #[tokio::test] async fn test_op_get_latest_nonce() { // 用别名调用函数 let res = op_xyz_fn().await; // 或者直接写完整路径:super::op_xyz().await; ... } }
额外说明
如果需要测试op在deno运行时的完整行为(比如从JS调用op),就得用插件提示的op_xyz::decl()来注册扩展,再通过deno_core的Runtime来测试:
#[cfg(test)] mod tests { use deno_core::{Extension, Runtime}; #[tokio::test] async fn test_op_in_runtime() { let ext = Extension::builder() .ops(vec![super::op_xyz::decl()]) .build(); let mut runtime = Runtime::new(ext).unwrap(); // 执行JS代码调用op let result = runtime.execute_script("test.js", r#" const result = await Deno.core.opAsync("xyz"); console.log(result); "#).await; assert!(result.is_ok()); } }
内容的提问来源于stack exchange,提问作者NewToCode
相关产品推荐
相关产品推荐

