使用Rust Mockall crate时returning方法未找到的问题求助
Mockall中
returning方法找不到的问题解决 问题场景
定义的Reader trait及实现:
#[cfg_attr(test, automock)] pub trait Reader { fn next_data(&mut self) -> &Data; } impl Reader for TestReader { fn next_data(&mut self) -> &Data { let data: &Data = &self.data[self.index]; self.index += 1; data } }
测试代码尝试配置MockReader时出错:
fn test_reader() { let data_iter: IntoIter<Data> = (some vector Vec<Data>).into_iter(); let mut reader = MockReader::new(); reader .expect_next_data() .times(2) .returning(move || data_iter.clone().next().is_some()); }
收到错误:
error[E0599]: no method named `returning` found for mutable reference `&mut __mock_MockReader_Reader::__next_data::Expectation` in the current scope --> src/tests/test_data.rs:177:14 | 174 | / reader 175 | | .expect_next_data() 176 | | .times(2) 177 | | .returning(move || data_iter.clone().next().is_some()); | | -^^^^^^^^^ method not found in `&mut Expectation` | |_____________| |
错误原因
- 返回值类型不匹配:原
trait方法next_data的返回值是&Data,但测试中闭包返回的是bool(is_some()的结果)。Mockall会根据trait方法的签名生成对应的Expectation类型,只有当闭包返回值类型与trait方法完全一致时,才会存在对应的returning方法。类型不匹配时,编译器找不到该方法。 - 迭代器使用错误:
IntoIter<Data>是拥有所有权的迭代器,clone()需要Data实现Clonetrait,且即使克隆,返回的是Data实例而非引用,和原方法的返回类型不符。
解决方案
1. 修正返回值类型,匹配trait方法签名
确保闭包返回&Data类型,同时保证数据的生命周期足够覆盖测试过程。示例代码:
fn test_reader() { // 初始化测试数据,放在栈上保证生命周期 let data_vec = vec![Data { /* 初始化字段 */ }, Data { /* 初始化字段 */ }]; // 使用iter()获取&Data的迭代器 let mut data_iter = data_vec.iter(); let mut reader = MockReader::new(); reader .expect_next_data() .times(2) .returning(move || { // 这里unwrap()假设我们确定有足够的元素,也可以用expect()处理测试失败 data_iter.next().expect("Insufficient data in iterator") }); }
2. 处理多次调用的引用返回(可选)
如果需要更灵活地处理引用返回,也可以使用Mockall提供的returning_ref方法(当返回引用时更直观):
fn test_reader() { let data = Data { /* 初始化字段 */ }; let mut reader = MockReader::new(); reader .expect_next_data() .times(2) .returning_ref(&data); }
3. 注意迭代器的生命周期
确保迭代器引用的数据不会在测试过程中被释放,比如将数据放在测试函数的栈上,避免使用临时变量导致生命周期不足。
内容的提问来源于stack exchange,提问作者leeway00
相关产品推荐
相关产品推荐

