如何在Rust中使用mockall约束方法调用顺序:确保func1优先于func2和func3执行
如何用Mockall仅强制func1先于func2/func3调用(不限制后两者顺序)
当然可以实现你想要的效果!你提到的mockall::Sequence完全能搞定这个场景,只是不用把三个函数都塞进同一个序列里——咱们换个思路拆分就行。
核心思路
我们只需要确保func1的调用必须发生在func2和func3之前,但不对func2和func3的相对调用顺序做约束。具体做法是:
- 创建一个序列,让
func1占据序列的第一个节点 - 让
func2和func3的调用期望都依赖这个节点(也就是要求它们必须在func1调用之后执行)
修改后的完整代码
下面是调整后的示例代码,重点修改了main函数部分:
extern crate mockall; use mockall::mock; use mockall::predicate::*; use mockall::Sequence; // 别忘了导入Sequence fn do_thing<T>(x: T) where T: TestTrait { x.func1(); x.func2(); x.func3(); } trait TestTrait { fn func1(self: &Self); fn func2(self: &Self); fn func3(self: &Self); } mock! { Test {} impl TestTrait for Test { fn func1(self: &Self); fn func2(self: &Self); fn func3(self: &Self); } } fn main() { let mut mock = MockTest::new(); let mut seq = Sequence::new(); // 让func1占据序列的第一个节点,返回可被依赖的调用节点 let func1_call = mock.expect_func1().returning(|| ()).in_sequence(&mut seq); // 让func2和func3都必须在func1调用之后执行,互相之间无顺序要求 mock.expect_func2().returning(|| ()).after(&func1_call); mock.expect_func3().returning(|| ()).after(&func1_call); // 两种合法顺序都会通过: // do_thing(mock); // 原顺序func1→func2→func3 // 如果修改do_thing为func1→func3→func2,也会通过 // 非法顺序(比如先调用func2再func1)会触发断言失败 }
关键代码解释
let mut seq = Sequence::new();:创建一个新的序列实例,用来标记调用顺序的依赖关系mock.expect_func1().in_sequence(&mut seq):把func1的调用期望绑定到序列的第一个位置,返回一个可以被其他期望依赖的节点对象.after(&func1_call):给func2和func3的调用期望添加依赖规则,要求它们必须在func1_call对应的调用(也就是func1的执行)完成之后才能被调用
这样设置后:
- ✅ 合法顺序:
func1→func2→func3、func1→func3→func2都会通过Mockall的断言验证 - ❌ 非法顺序:任何先调用
func2或func3再调用func1的情况,都会触发Mockall的调用顺序断言失败
内容的提问来源于stack exchange,提问作者LHLaurini
相关产品推荐
相关产品推荐

